[evolution-data-server/camel-socks-proxy-master: 1/10] Do name resolution inside camel_tcp_stream_connect()



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]