[Commits] [SCM] claws branch, master, updated. 3.12.0-54-g8f4236e

ticho at claws-mail.org ticho at claws-mail.org
Thu Aug 20 08:28:37 CEST 2015


The branch, master has been updated
       via  8f4236e282d3252ecf9f3920e2e5c312d2cf50fc (commit)
      from  1b32cc6794190c9fb6124b6de5b6f23e3007eec9 (commit)

Summary of changes:
 src/common/socket.c |  195 ++++++---------------------------------------------
 src/common/socket.h |    2 -
 src/common/utils.c  |   21 ++++--
 3 files changed, 37 insertions(+), 181 deletions(-)


- Log -----------------------------------------------------------------
commit 8f4236e282d3252ecf9f3920e2e5c312d2cf50fc
Author: Andrej Kacian <ticho at claws-mail.org>
Date:   Wed Oct 1 22:00:06 2014 +0200

    Use getaddrinfo() instead of gethostbyname() in socket.c.
    
    Closes bug #3253, as we're trying all resolved addresses.
    This should also make IPv6 work on Windows, bug #3495.

diff --git a/src/common/socket.c b/src/common/socket.c
index f842c8d..99a9774 100644
--- a/src/common/socket.c
+++ b/src/common/socket.c
@@ -151,14 +151,8 @@ static gint sock_connect_with_timeout	(gint			 sock,
 					 gint			 addrlen,
 					 guint			 timeout_secs);
 
-#ifndef INET6
-static gint sock_connect_by_hostname	(gint		 sock,
-					 const gchar	*hostname,
-					 gushort	 port);
-#else
 static gint sock_connect_by_getaddrinfo	(const gchar	*hostname,
 					 gushort	 port);
-#endif
 
 static SockInfo *sockinfo_from_fd(const gchar *hostname,
 				  gushort port,
@@ -615,98 +609,6 @@ static gint sock_connect_with_timeout(gint sock,
 	return ret;
 }
 
-struct hostent *my_gethostbyname(const gchar *hostname)
-{
-	struct hostent *hp;
-#ifdef G_OS_UNIX
-	void (*prev_handler)(gint);
-	
-	alarm(0);
-	prev_handler = signal(SIGALRM, timeout_handler);
-	if (sigsetjmp(jmpenv, 1)) {
-		alarm(0);
-		signal(SIGALRM, prev_handler);
-		g_printerr("%s: host lookup timed out.\n", hostname);
-		log_error(LOG_PROTOCOL, _("%s: host lookup timed out.\n"), hostname);
-		errno = 0;
-		return NULL;
-	}
-	alarm(io_timeout);
-#endif
-
-	if ((hp = gethostbyname(hostname)) == NULL) {
-#ifdef G_OS_UNIX
-		alarm(0);
-		signal(SIGALRM, prev_handler);
-#endif
-		g_printerr("%s: unknown host.\n", hostname);
-		log_error(LOG_PROTOCOL, _("%s: unknown host.\n"), hostname);
-		errno = 0;
-		return NULL;
-	}
-
-#ifdef G_OS_UNIX
-	alarm(0);
-	signal(SIGALRM, prev_handler);
-#endif
-
-	return hp;
-}
-
-#ifndef INET6
-static gint my_inet_aton(const gchar *hostname, struct in_addr *inp)
-{
-#if HAVE_INET_ATON
-	return inet_aton(hostname, inp);
-#else
-#if HAVE_INET_ADDR
-	guint32 inaddr;
-
-	inaddr = inet_addr(hostname);
-	if (inaddr != -1) {
-		memcpy(inp, &inaddr, sizeof(inaddr));
-		return 1;
-	} else
-		return 0;
-#else
-	return 0;
-#endif
-#endif /* HAVE_INET_ATON */
-}
-
-static gint sock_connect_by_hostname(gint sock, const gchar *hostname,
-				     gushort port)
-{
-	struct hostent *hp;
-	struct sockaddr_in ad;
-
-	memset(&ad, 0, sizeof(ad));
-	ad.sin_family = AF_INET;
-	ad.sin_port = htons(port);
-
-	refresh_resolvers();
-
-	if (!my_inet_aton(hostname, &ad.sin_addr)) {
-		if ((hp = my_gethostbyname(hostname)) == NULL) {
-			g_printerr("%s: unknown host.\n", hostname);
-			errno = 0;
-			return -1;
-		}
-
-		if (hp->h_length != 4 && hp->h_length != 8) {
-			g_printerr("illegal address length received for host %s\n", hostname);
-			errno = 0;
-			return -1;
-		}
-
-		memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
-	}
-
-	return sock_connect_with_timeout(sock, (struct sockaddr *)&ad,
-					 sizeof(ad), io_timeout);
-}
-
-#else /* INET6 */
 static gint sock_connect_by_getaddrinfo(const gchar *hostname, gushort	port)
 {
 	gint sock = -1, gai_error;
@@ -716,8 +618,14 @@ static gint sock_connect_by_getaddrinfo(const gchar *hostname, gushort	port)
 	refresh_resolvers();
 
 	memset(&hints, 0, sizeof(hints));
-	/* hints.ai_flags = AI_CANONNAME; */
+	hints.ai_flags = AI_ADDRCONFIG;
+
+#ifdef INET6
 	hints.ai_family = AF_UNSPEC;
+#else
+	hints.ai_family = AF_INET;
+#endif
+
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_protocol = IPPROTO_TCP;
 
@@ -731,9 +639,18 @@ static gint sock_connect_by_getaddrinfo(const gchar *hostname, gushort	port)
 	}
 
 	for (ai = res; ai != NULL; ai = ai->ai_next) {
+#ifndef INET6
+		if (ai->ai_family == AF_INET6)
+			continue;
+#endif
+
 		sock = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-		if (sock < 0)
+		if (sock < 0 )
+			continue;
+#ifdef G_OS_WIN32
+		if (sock == INVALID_SOCKET)
 			continue;
+#endif
 
 		if (sock_connect_with_timeout
 			(sock, ai->ai_addr, ai->ai_addrlen, io_timeout) == 0)
@@ -750,7 +667,6 @@ static gint sock_connect_by_getaddrinfo(const gchar *hostname, gushort	port)
 
 	return sock;
 }
-#endif /* !INET6 */
 
 SockInfo *sock_connect(const gchar *hostname, gushort port)
 {
@@ -760,27 +676,10 @@ SockInfo *sock_connect(const gchar *hostname, gushort port)
 	gint sock;
 #endif
 
-#ifdef INET6
-	if ((sock = sock_connect_by_getaddrinfo(hostname, port)) < 0)
-		return NULL;
-#else
-#ifdef G_OS_WIN32
-	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
-		g_warning("socket() failed: %d\n", WSAGetLastError());
-#else
-	if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
-		perror("socket");
-#endif /* G_OS_WIN32 */
+	if ((sock = sock_connect_by_getaddrinfo(hostname, port)) < 0) {
 		return NULL;
 	}
 
-	if (sock_connect_by_hostname(sock, hostname, port) < 0) {
-		if (errno != 0) perror("connect");
-		close(sock);
-		return NULL;
-	}
-#endif /* INET6 */
-
 	return sockinfo_from_fd(hostname, port, sock);
 }
 
@@ -1133,15 +1032,9 @@ static gboolean sock_get_address_info_async_cb(GIOChannel *source,
 static void address_info_async_child(void *opaque)
 {
         SockLookupData *parm = opaque;
-#ifdef INET6
         gint gai_err;
         struct addrinfo hints, *res, *ai;
         gchar port_str[6];
-#else /* !INET6 */
-        struct hostent *hp;
-        gchar **addr_list_p;
-        struct sockaddr_in ad;
-#endif /* INET6 */
         gint ai_member[4] = {AF_UNSPEC, 0, 0, 0};
 
 #ifndef G_OS_WIN32
@@ -1149,10 +1042,13 @@ static void address_info_async_child(void *opaque)
         parm->pipe_fds[0] = -1;
 #endif
 
-#ifdef INET6
         memset(&hints, 0, sizeof(hints));
-        hints.ai_flags = AI_CANONNAME;
+        hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG;
+#ifdef INET6
         hints.ai_family = AF_UNSPEC;
+#else
+				hints.ai_family = AF_INET;
+#endif
         hints.ai_socktype = SOCK_STREAM;
         hints.ai_protocol = IPPROTO_TCP;
 
@@ -1210,51 +1106,6 @@ static void address_info_async_child(void *opaque)
 
         if (res != NULL)
                 freeaddrinfo(res);
-#else /* !INET6 */
-        hp = my_gethostbyname(parm->hostname);
-        if (hp == NULL || hp->h_addrtype != AF_INET) {
-		gchar len = 0;
- 	        fd_write_all(parm->pipe_fds[1], &len,
-                     sizeof(len));
-                fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
-                             sizeof(ai_member));
-               close(parm->pipe_fds[1]);
-                parm->pipe_fds[1] = -1;
-#ifdef G_OS_WIN32
-                _endthread();
-#else
-                _exit(1);
-#endif
-        }
-
-        ai_member[0] = AF_INET;
-        ai_member[1] = SOCK_STREAM;
-        ai_member[2] = IPPROTO_TCP;
-        ai_member[3] = sizeof(ad);
-
-        memset(&ad, 0, sizeof(ad));
-        ad.sin_family = AF_INET;
-        ad.sin_port = htons(parm->port);
-
-	if (hp->h_name && strlen(hp->h_name) < 255) {
-		gchar len = strlen(hp->h_name);
-	        fd_write_all(parm->pipe_fds[1], &len,
-                     sizeof(len));
-	        fd_write_all(parm->pipe_fds[1], hp->h_name,
-                     len);			 
-	} else {
-		gchar len = 0;
- 	        fd_write_all(parm->pipe_fds[1], &len,
-                     sizeof(len));
-	}
-        for (addr_list_p = hp->h_addr_list; *addr_list_p != NULL;
-             addr_list_p++) {
-                memcpy(&ad.sin_addr, *addr_list_p, hp->h_length);
-                fd_write_all(parm->pipe_fds[1], (gchar *)ai_member,
-                             sizeof(ai_member));
-                fd_write_all(parm->pipe_fds[1], (gchar *)&ad, sizeof(ad));
-        }
-#endif /* INET6 */
 
         close(parm->pipe_fds[1]);
         parm->pipe_fds[1] = -1;
diff --git a/src/common/socket.h b/src/common/socket.h
index 59cb230..fb20233 100644
--- a/src/common/socket.h
+++ b/src/common/socket.h
@@ -94,8 +94,6 @@ gboolean sock_is_nonblocking_mode	(SockInfo *sock);
 guint sock_add_watch			(SockInfo *sock, GIOCondition condition,
 					 SockFunc func, gpointer data);
 
-struct hostent *my_gethostbyname	(const gchar *hostname);
-
 SockInfo *sock_connect			(const gchar *hostname, gushort port);
 gint sock_connect_async			(const gchar *hostname, gushort port,
 					 SockConnectFunc func, gpointer data);
diff --git a/src/common/utils.c b/src/common/utils.c
index 64ca25a..0424ceb 100644
--- a/src/common/utils.c
+++ b/src/common/utils.c
@@ -1976,21 +1976,28 @@ const gchar *get_domain_name(void)
 {
 #ifdef G_OS_UNIX
 	static gchar *domain_name = NULL;
+	struct addrinfo hints, *res;
+	char hostname[256];
+	int s;
 
 	if (!domain_name) {
-		struct hostent *hp;
-		char hostname[256];
-
 		if (gethostname(hostname, sizeof(hostname)) != 0) {
 			perror("gethostname");
 			domain_name = "localhost";
 		} else {
-			hostname[sizeof(hostname) - 1] = '\0';
-			if ((hp = my_gethostbyname(hostname)) == NULL) {
-				perror("gethostbyname");
+			memset(&hints, 0, sizeof(struct addrinfo));
+			hints.ai_family = AF_UNSPEC;
+			hints.ai_socktype = 0;
+			hints.ai_flags = AI_CANONNAME;
+			hints.ai_protocol = 0;
+
+			s = getaddrinfo(hostname, NULL, &hints, &res);
+			if (s != 0) {
+				fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s));
 				domain_name = g_strdup(hostname);
 			} else {
-				domain_name = g_strdup(hp->h_name);
+				domain_name = g_strdup(res->ai_canonname);
+				freeaddrinfo(res);
 			}
 		}
 		debug_print("domain name = %s\n", domain_name);

-----------------------------------------------------------------------


hooks/post-receive
-- 
Claws Mail


More information about the Commits mailing list