[evolution-data-server/camel-socks-proxy-master: 1/10] Do name resolution inside camel_tcp_stream_connect()
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/camel-socks-proxy-master: 1/10] Do name resolution inside camel_tcp_stream_connect()
- Date: Sat, 24 Jul 2010 03:06:00 +0000 (UTC)
commit f045938ff9276b74b1f6f3a2aff48dac6c76d514
Author: Federico Mena Quintero <federico novell com>
Date: Fri Jul 9 14:12:06 2010 -0500
Do name resolution inside camel_tcp_stream_connect()
This function and the associated vmethod used to take a struct addrinfo *.
However, this doesn't let us have SOCKS4a or SOCKS5 proxies that do name
resolution in the proxy. So, now the main camel_tcp_stream_connect() takes
a hostname and service name, and implementations do name resolution
by themselves. Later we will modify the proxy code to do name resolution
in the proxy.
We allow passing a fallback port to camel_tcp_stream_connect(), which
is used by Camel's providers when the system's services database
(/etc/services) doesn't have an entry for a particular service name.
If getaddrinfo() can't find the service name, then we use a
fallback/hardcoded port number. See bgo#267898
Signed-off-by: Federico Mena Quintero <federico novell com>
camel/camel-tcp-stream-raw.c | 51 +++++++++++++++++++++++++++++++++--------
camel/camel-tcp-stream-ssl.c | 51 ++++++++++++++++++++++++++++++++++-------
camel/camel-tcp-stream.c | 12 ++++++---
camel/camel-tcp-stream.h | 4 +-
4 files changed, 93 insertions(+), 25 deletions(-)
---
diff --git a/camel/camel-tcp-stream-raw.c b/camel/camel-tcp-stream-raw.c
index ff07048..858cfdd 100644
--- a/camel/camel-tcp-stream-raw.c
+++ b/camel/camel-tcp-stream-raw.c
@@ -424,7 +424,7 @@ connect_to_socks4_proxy (const gchar *proxy_host, gint proxy_port, struct addrin
goto error;
}
- g_assert (connect_addr->ai_addr->sa_family == AF_INET); /* FIXME: what to do about IPv6? Are we just screwed with SOCKS4? */
+ g_assert (connect_addr->ai_addr->sa_family == AF_INET); /* FMQ: check for AF_INET in the caller */
sin = (struct sockaddr_in *) connect_addr->ai_addr;
request[0] = 0x04; /* SOCKS4 */
@@ -466,30 +466,61 @@ out:
static gint
tcp_stream_raw_connect (CamelTcpStream *stream,
- struct addrinfo *host,
+ const char *host, const char *service, gint fallback_port,
GError **error)
{
CamelTcpStreamRaw *raw = CAMEL_TCP_STREAM_RAW (stream);
+ struct addrinfo *addr, *ai;
+ struct addrinfo hints;
+ GError *my_error;
+ gint retval;
const gchar *proxy_host;
gint proxy_port;
- g_return_val_if_fail (host != NULL, -1);
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+
+ my_error = NULL;
+ addr = camel_getaddrinfo (host, service, &hints, &my_error);
+ if (addr == NULL && fallback_port != 0 && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ char str_port[16];
+
+ g_clear_error (&my_error);
+ sprintf (str_port, "%d", fallback_port);
+ addr = camel_getaddrinfo (host, str_port, &hints, &my_error);
+ }
+
+ if (addr == NULL) {
+ g_propagate_error (error, my_error);
+ return -1;
+ }
camel_tcp_stream_peek_socks_proxy (stream, &proxy_host, &proxy_port);
- while (host) {
+ ai = addr;
+
+ while (ai) {
if (proxy_host)
- raw->sockfd = connect_to_socks4_proxy (proxy_host, proxy_port, host);
+ raw->sockfd = connect_to_socks4_proxy (proxy_host, proxy_port, ai);
else
- raw->sockfd = socket_connect (host);
+ raw->sockfd = socket_connect (ai);
- if (raw->sockfd != -1)
- return 0;
+ if (raw->sockfd != -1) {
+ retval = 0;
+ goto out;
+ }
- host = host->ai_next;
+ ai = ai->ai_next;
}
- return -1;
+ retval = -1;
+
+out:
+
+ camel_freeaddrinfo (addr);
+
+ return retval;
}
static gint
diff --git a/camel/camel-tcp-stream-ssl.c b/camel/camel-tcp-stream-ssl.c
index cf386f7..3fe56de 100644
--- a/camel/camel-tcp-stream-ssl.c
+++ b/camel/camel-tcp-stream-ssl.c
@@ -1194,7 +1194,7 @@ connect_to_socks4_proxy (CamelTcpStreamSSL *ssl, const gchar *proxy_host, gint p
goto error;
}
- g_assert (connect_addr->ai_addr->sa_family == AF_INET); /* FIXME: what to do about IPv6? Are we just screwed with SOCKS4? */
+ g_assert (connect_addr->ai_addr->sa_family == AF_INET); /* FMQ: check for AF_INET in the caller */
sin = (struct sockaddr_in *) connect_addr->ai_addr;
request[0] = 0x04; /* SOCKS4 */
@@ -1267,28 +1267,61 @@ out:
static gint
tcp_stream_ssl_connect (CamelTcpStream *stream,
- struct addrinfo *host,
+ const char *host, const char *service, gint fallback_port,
GError **error)
{
CamelTcpStreamSSL *ssl = CAMEL_TCP_STREAM_SSL (stream);
+ struct addrinfo *addr, *ai;
+ struct addrinfo hints;
+ GError *my_error;
+ gint retval;
const gchar *proxy_host;
gint proxy_port;
+ memset (&hints, 0, sizeof (hints));
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_family = PF_UNSPEC;
+
+ my_error = NULL;
+ addr = camel_getaddrinfo (host, service, &hints, &my_error);
+ if (addr == NULL && fallback_port != 0 && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
+ char str_port[16];
+
+ g_clear_error (&my_error);
+ sprintf (str_port, "%d", fallback_port);
+ addr = camel_getaddrinfo (host, str_port, &hints, &my_error);
+ }
+
+ if (addr == NULL) {
+ g_propagate_error (error, my_error);
+ return -1;
+ }
+
camel_tcp_stream_peek_socks_proxy (stream, &proxy_host, &proxy_port);
- while (host) {
+ ai = addr;
+
+ while (ai) {
if (proxy_host)
- ssl->priv->sockfd = connect_to_socks4_proxy (ssl, proxy_host, proxy_port, host);
+ ssl->priv->sockfd = connect_to_socks4_proxy (ssl, proxy_host, proxy_port, ai);
else
- ssl->priv->sockfd = tcp_socket_ssl_connect (stream, host, TRUE);
+ ssl->priv->sockfd = socket_connect (stream, ai, TRUE);
- if (ssl->priv->sockfd)
- return 0;
+ if (ssl->priv->sockfd) {
+ retval = 0;
+ goto out;
+ }
- host = host->ai_next;
+ ai = ai->ai_next;
}
- return -1;
+ retval = -1;
+
+out:
+
+ camel_freeaddrinfo (addr);
+
+ return retval;
}
static gint
diff --git a/camel/camel-tcp-stream.c b/camel/camel-tcp-stream.c
index cb0b866..23ddb6f 100644
--- a/camel/camel-tcp-stream.c
+++ b/camel/camel-tcp-stream.c
@@ -82,8 +82,9 @@ camel_tcp_stream_init (CamelTcpStream *tcp_stream)
/**
* camel_tcp_stream_connect:
* @stream: a #CamelTcpStream object
- * @host: a linked list of addrinfo structures to try to connect, in
- * the order of most likely to least likely to work.
+ * @host: Hostname for connection
+ * @service: Service name or port number in string form
+ * @fallback_port: Port number to retry if @service is not present in the system's services database, or 0 to avoid retrying.
* @error: return location for a #GError, or %NULL
*
* Create a socket and connect based upon the data provided.
@@ -92,18 +93,21 @@ camel_tcp_stream_init (CamelTcpStream *tcp_stream)
**/
gint
camel_tcp_stream_connect (CamelTcpStream *stream,
- struct addrinfo *host,
+ const char *host, const char *service, gint fallback_port,
GError **error)
{
CamelTcpStreamClass *class;
gint retval;
g_return_val_if_fail (CAMEL_IS_TCP_STREAM (stream), -1);
+ g_return_val_if_fail (host != NULL, -1);
+ g_return_val_if_fail (service != NULL, -1);
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
class = CAMEL_TCP_STREAM_GET_CLASS (stream);
g_return_val_if_fail (class->connect != NULL, -1);
- retval = class->connect (stream, host, error);
+ retval = class->connect (stream, host, service, fallback_port, error);
CAMEL_CHECK_GERROR (stream, connect, retval == 0, error);
return retval;
diff --git a/camel/camel-tcp-stream.h b/camel/camel-tcp-stream.h
index 5c97ea3..389d1fe 100644
--- a/camel/camel-tcp-stream.h
+++ b/camel/camel-tcp-stream.h
@@ -123,7 +123,7 @@ struct _CamelTcpStreamClass {
CamelStreamClass parent_class;
gint (*connect) (CamelTcpStream *stream,
- struct addrinfo *host,
+ const char *host, const char *service, gint fallback_port,
GError **error);
gint (*getsockopt) (CamelTcpStream *stream,
CamelSockOptData *data);
@@ -139,7 +139,7 @@ struct _CamelTcpStreamClass {
GType camel_tcp_stream_get_type (void);
gint camel_tcp_stream_connect (CamelTcpStream *stream,
- struct addrinfo *host,
+ const char *host, const char *service, gint fallback_port,
GError **error);
gint camel_tcp_stream_getsockopt (CamelTcpStream *stream,
CamelSockOptData *data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]