commit cb067155841675b02bd406525219122642161208
Author: Oswald Buddenhagen <[email protected]>
Date:   Sun Sep 1 17:35:31 2013 +0200

    IPv6 support
    
    inspired by a patch by "Todd T. Fries" <[email protected]>.

 configure.ac |    9 ++++++++
 src/isync.h  |    4 +++
 src/socket.c |   56 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 69 insertions(+), 0 deletions(-)

diff --git a/configure.ac b/configure.ac
index 0bfaa74..479fff3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -35,6 +35,15 @@ AC_CHECK_LIB(socket, socket, [SOCK_LIBS="-lsocket"])
 AC_CHECK_LIB(nsl, inet_ntoa, [SOCK_LIBS="$SOCK_LIBS -lnsl"])
 AC_SUBST(SOCK_LIBS)
 
+have_ipv6=true
+sav_LDFLAGS=$LDFLAGS
+LDFLAGS="$LDFLAGS $SOCK_LIBS"
+AC_CHECK_FUNCS(getaddrinfo inet_ntop, , [have_ipv6=false])
+LDFLAGS=$sav_LDFLAGS
+if $have_ipv6; then
+    AC_DEFINE(HAVE_IPV6, 1, [if your libc has IPv6 support])
+fi
+
 have_ssl_paths=
 AC_ARG_WITH(ssl,
   AC_HELP_STRING([--with-ssl[=PATH]], [where to look for SSL [detect]]),
diff --git a/src/isync.h b/src/isync.h
index c006d71..661c1ee 100644
--- a/src/isync.h
+++ b/src/isync.h
@@ -85,7 +85,11 @@ typedef struct {
        int fd;
        int state;
        const server_conf_t *conf; /* needed during connect */
+#ifdef HAVE_IPV6
+       struct addrinfo *addrs, *curr_addr; /* needed during connect */
+#else
        char **curr_addr; /* needed during connect */
+#endif
        char *name;
 #ifdef HAVE_LIBSSL
        SSL *ssl;
diff --git a/src/socket.c b/src/socket.c
index a04c686..07d9bb7 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -346,6 +346,24 @@ socket_connect( conn_t *sock, void (*cb)( int ok, void 
*aux ) )
                info( "\vok\n" );
                socket_connected( sock );
        } else {
+#ifdef HAVE_IPV6
+               int gaierr;
+               struct addrinfo hints;
+
+               memset( &hints, 0, sizeof(hints) );
+               hints.ai_family = AF_UNSPEC;
+               hints.ai_socktype = SOCK_STREAM;
+               hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG;
+               infon( "Resolving %s... ", conf->host );
+               if ((gaierr = getaddrinfo( conf->host, NULL, &hints, 
&sock->addrs ))) {
+                       error( "IMAP error: Cannot resolve server '%s': %s\n", 
conf->host, gai_strerror( gaierr ) );
+                       socket_connect_bail( sock );
+                       return;
+               }
+               info( "\vok\n" );
+
+               sock->curr_addr = sock->addrs;
+#else
                struct hostent *he;
 
                infon( "Resolving %s... ", conf->host );
@@ -358,6 +376,7 @@ socket_connect( conn_t *sock, void (*cb)( int ok, void *aux 
) )
                info( "\vok\n" );
 
                sock->curr_addr = he->h_addr_list;
+#endif
                socket_connect_one( sock );
        }
 }
@@ -367,11 +386,19 @@ socket_connect_one( conn_t *sock )
 {
        int s;
        ushort port;
+#ifdef HAVE_IPV6
+       struct addrinfo *ai;
+#else
        struct {
                struct sockaddr_in ai_addr[1];
        } ai[1];
+#endif
 
+#ifdef HAVE_IPV6
+       if (!(ai = sock->curr_addr)) {
+#else
        if (!*sock->curr_addr) {
+#endif
                error( "No working address found for %s\n", sock->conf->host );
                socket_connect_bail( sock );
                return;
@@ -382,17 +409,32 @@ socket_connect_one( conn_t *sock )
               sock->conf->use_imaps ? 993 :
 #endif
               143;
+#ifdef HAVE_IPV6
+       if (ai->ai_family == AF_INET6) {
+               struct sockaddr_in6 *in6 = ((struct sockaddr_in6 *)ai->ai_addr);
+               char sockname[64];
+               in6->sin6_port = htons( port );
+               nfasprintf( &sock->name, "%s ([%s]:%hu)",
+                           sock->conf->host, inet_ntop( AF_INET6, 
&in6->sin6_addr, sockname, sizeof(sockname) ), port );
+       } else
+#endif
        {
                struct sockaddr_in *in = ((struct sockaddr_in *)ai->ai_addr);
+#ifndef HAVE_IPV6
                memset( in, 0, sizeof(*in) );
                in->sin_family = AF_INET;
                in->sin_addr.s_addr = *((int *)*sock->curr_addr);
+#endif
                in->sin_port = htons( port );
                nfasprintf( &sock->name, "%s (%s:%hu)",
                            sock->conf->host, inet_ntoa( in->sin_addr ), port );
        }
 
+#ifdef HAVE_IPV6
+       s = socket( ai->ai_family, SOCK_STREAM, 0 );
+#else
        s = socket( PF_INET, SOCK_STREAM, 0 );
+#endif
        if (s < 0) {
                perror( "socket" );
                exit( 1 );
@@ -402,7 +444,11 @@ socket_connect_one( conn_t *sock )
        add_fd( s, socket_fd_cb, sock );
 
        infon( "Connecting to %s... ", sock->name );
+#ifdef HAVE_IPV6
+       if (connect( s, ai->ai_addr, ai->ai_addrlen )) {
+#else
        if (connect( s, ai->ai_addr, sizeof(*ai->ai_addr) )) {
+#endif
                if (errno != EINPROGRESS) {
                        socket_connect_failed( sock );
                        return;
@@ -423,13 +469,20 @@ socket_connect_failed( conn_t *conn )
        socket_close_internal( conn );
        free( conn->name );
        conn->name = 0;
+#ifdef HAVE_IPV6
+       conn->curr_addr = conn->curr_addr->ai_next;
+#else
        conn->curr_addr++;
+#endif
        socket_connect_one( conn );
 }
 
 static void
 socket_connected( conn_t *conn )
 {
+#ifdef HAVE_IPV6
+       freeaddrinfo( conn->addrs );
+#endif
        conf_fd( conn->fd, 0, POLLIN );
        conn->state = SCK_READY;
        conn->callbacks.connect( 1, conn->callback_aux );
@@ -438,6 +491,9 @@ socket_connected( conn_t *conn )
 static void
 socket_connect_bail( conn_t *conn )
 {
+#ifdef HAVE_IPV6
+       freeaddrinfo( conn->addrs );
+#endif
        free( conn->name );
        conn->name = 0;
        conn->callbacks.connect( 0, conn->callback_aux );

------------------------------------------------------------------------------
Learn the latest--Visual Studio 2012, SharePoint 2013, SQL 2012, more!
Discover the easy way to master current and previous Microsoft technologies
and advance your career. Get an incredible 1,500+ hours of step-by-step
tutorial videos with LearnDevNow. Subscribe today and save!
http://pubads.g.doubleclick.net/gampad/clk?id=58040911&iu=/4140/ostg.clktrk
_______________________________________________
isync-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel

Reply via email to