Your message dated Fri, 22 Sep 2006 02:17:19 -0700
with message-id <[EMAIL PROTECTED]>
and subject line Bug#370022: fixed in up-imapproxy 1.2.4-5
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: imapproxy
Version: 1.2.4-4
Severity: wishlist
Justification: "Pervasive IPv6 support" release goal

(http://lists.debian.org/debian-devel-announce/2006/05/msg00015.html)

Perhaps not the most important application to make IPv6 capable, but since the 
proxy and the target IMAP server can run on a different machines, IPv6 can be 
useful (at least in the future, when nobody uses IPv4 anymore).

I think I've fixed this already with my attached patch, but I'm wondering:

I assume all changes should be in #ifdef HAVE_IPV6 blocks, leaving the code 
unchanged if HAVE_IPV6 is undefined.

What the heck is ISD.host used for? The result from gethostbyname() is copied 
there (shallowly), but then it's never used, right? And whatever is the 
servent structure good for? Shouldn't just a port number be enough?

Does the addrlen argument to connect(2) have to equal sizeof struct 
sockaddr_in or sizeof struct sockaddr_in6 depending on the socket type and 
the s?_family field of the sockaddr structure? It seems that a larger value 
is OK too.

So what my patch does is this (when HAVE_IPV6 is defined):

* Replaces statically allocated sockaddr_in structs with sockaddr_storage.
* Uses getaddrinfo() instead of gethostbyname() to resolve server_hostname.
* Tries all addresses returned by getaddrinfo().
* Uses inet_pton() instead of inet_addr() to parse listen_addr.
* Changes the server_port configuration option to be a string, since 
getaddrinfo() wants a string (which can then be a service name 
from /etc/services) to fill out the port fields of the sockaddr structures of 
the returned addrinfo structures.
* Gets rid of the superflous fields from struct IMAPServerDescriptor and adds 
an addrinfo pointer instead, to carry the getaddrinfo() result from 
ServerInit() to SetBannerAndCapability().
* Add a --enable-ipv6 parameter to ./configure, or rather configure.in. 
However, autoconf and autoheaders aren't run by debian/rules, so that needs 
to be done and the changes included in the diff.

I also discovered a couple of other oddities such as no default value for 
server_port, and the loop in SetBannerAndCapability() always breaks 
(commented with "Success"), even if connect() fails.

-- 
Magnus Holmgren        [EMAIL PROTECTED]
                       (No Cc of list mail needed, thanks)
diff -bwu up-imapproxy-1.2.4/src/imapcommon.c up-imapproxy-1.2.4/src/imapcommon.c
--- up-imapproxy-1.2.4/src/imapcommon.c
+++ up-imapproxy-1.2.4/src/imapcommon.c
@@ -498,7 +498,11 @@
      */
     Server.conn = ( ICD_Struct * ) malloc( sizeof ( ICD_Struct ) );
     memset( Server.conn, 0, sizeof ( ICD_Struct ) );
+#ifdef HAVE_IPV6
+    Server.conn->sd = socket( ISD.srv.ss_family, SOCK_STREAM, IPPROTO_TCP );
+#else
     Server.conn->sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
+#endif
     if ( Server.conn->sd == -1 )
     {
 	syslog(LOG_INFO, "LOGIN: '%s' (%s:%d) failed: Unable to open server socket: %s", Username, ClientAddr, sin_port, strerror( errno ) );
diff -bwu up-imapproxy-1.2.4/src/main.c up-imapproxy-1.2.4/src/main.c
--- up-imapproxy-1.2.4/src/main.c
+++ up-imapproxy-1.2.4/src/main.c
@@ -253,8 +253,13 @@
     int listensd;                      /* socket descriptor we'll bind to */
     int clientsd;                      /* incoming socket descriptor */
     int addrlen;                       
+#ifdef HAVE_IPV6
+    struct sockaddr_storage srvaddr;
+    struct sockaddr_storage cliaddr;
+#else
     struct sockaddr_in srvaddr;
     struct sockaddr_in cliaddr;
+#endif
     pthread_t ThreadId;                /* thread id of each incoming conn */
     pthread_t RecycleThread;           /* used just for the recycle thread */
     pthread_attr_t attr;               /* generic thread attribute struct */
@@ -494,6 +499,37 @@
     }
     
     memset( (char *) &srvaddr, 0, sizeof srvaddr );
+#ifdef HAVE_IPV6 
+    if ( !PC_Struct.listen_addr ) {
+      srvaddr.ss_family = PF_INET;
+      ((struct sockaddr_in*)&srvaddr)->sin_addr.s_addr = htonl(INADDR_ANY);
+    }
+    else if (inet_pton(AF_INET6, PC_Struct.listen_addr, 
+		       &((struct sockaddr_in6*)&srvaddr)->sin6_addr) > 0) {
+      srvaddr.ss_family = PF_INET6;
+    }
+    else if (inet_pton(AF_INET, PC_Struct.listen_addr, 
+		       &((struct sockaddr_in*)&srvaddr)->sin_addr) > 0) {
+      srvaddr.ss_family = PF_INET;
+    }
+    else {
+      syslog( LOG_ERR, "%s: bad bind address: '%s' specified in config file.  Exiting.", fn, PC_Struct.listen_addr );
+      exit( 1 );
+    }
+
+    syslog(LOG_INFO, "%s: Binding to tcp %s:%d", fn, PC_Struct.listen_addr ?
+	   PC_Struct.listen_addr : "*", PC_Struct.listen_port );
+
+    if (srvaddr.ss_family == PF_INET6) {
+      ((struct sockaddr_in6*)&srvaddr)->sin6_port = htons(PC_Struct.listen_port);
+      listensd = socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
+    }
+    else {
+      ((struct sockaddr_in*)&srvaddr)->sin_port = htons(PC_Struct.listen_port);
+      listensd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+    }
+
+#else
     srvaddr.sin_family = PF_INET;
     if ( !PC_Struct.listen_addr )
     {
@@ -515,6 +551,8 @@
     srvaddr.sin_port = htons(PC_Struct.listen_port);
 
     listensd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
+#endif
+
     if ( listensd == -1 )
     {
 	syslog(LOG_ERR, "%s: socket() failed: %s", fn, strerror(errno));
@@ -710,7 +748,11 @@
 static void ServerInit( void ) 
 {
     char *fn = "ServerInit()";
+#ifdef HAVE_IPV6
+    struct addrinfo hints, *ai;
+#else
     struct hostent *hp;
+#endif
     struct rlimit rl;
     int rc;
     struct passwd *pw;
@@ -765,6 +807,34 @@
     /* grab a host entry for the imap server. */
     syslog( LOG_INFO, "%s: proxying to IMAP server '%s'.", fn, 
 	    PC_Struct.server_hostname );
+#ifdef HAVE_IPV6
+    memset(&hints, 0, sizeof(struct addrinfo));
+    hints.ai_socktype = SOCK_STREAM;
+    hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
+
+    for( ;; )
+    {
+	rc = getaddrinfo( PC_Struct.server_hostname, PC_Struct.server_port, &hints, &ai );
+	
+	if ( rc )
+	{
+	    syslog(LOG_ERR, "%s: gethostbyname() failed to resolve hostname of remote IMAP server: %s -- retrying", fn, strerror(errno) );
+	    sleep( 15 );
+	}
+	else
+	{
+	    break;
+	}
+    }
+    syslog(LOG_INFO, "%s: Proxying to IMAP port %s", 
+	   fn, PC_Struct.server_port );
+        
+    /* 
+     * we fill in our global socket address structure in SetBannerAndCapability, 
+     * the possibly several addresses belonging to the hostname can be tried.
+     */
+    ISD.ai = ai;
+#else
     
     for( ;; )
     {
@@ -794,6 +864,7 @@
     ISD.srv.sin_family = PF_INET;
     memcpy( &ISD.srv.sin_addr.s_addr, ISD.host.h_addr, ISD.host.h_length );
     ISD.srv.sin_port = ISD.serv.s_port;
+#endif
 }
 
 
@@ -955,10 +1026,43 @@
     int BytesRead;
     char *fn = "SetBannerAndCapability()";
     int NumRef = 0;
+#ifdef HAVE_IPV6
+    struct addrinfo *ai;
+    int addrlen;
+#endif
 
     /* initialize some stuff */
     memset( &itd, 0, sizeof itd );
 
+#ifdef HAVE_IPV6
+
+    for ( ai = ISD.ai; ; ai = ai->ai_next ) {
+        addrlen = ai->ai_family == PF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in);
+
+	sd = socket( ai->ai_family, SOCK_STREAM, IPPROTO_TCP );
+	if ( sd == -1 )
+	{
+	    syslog(LOG_ERR, "%s: socket() failed: %s -- exiting", fn, strerror(errno));
+	    exit( 1 );
+	}
+     
+	if ( connect( sd, ai->ai_addr, addrlen ) == -1 ) {
+	    
+	    syslog(LOG_WARNING, "%s: connect() to imap server on socket [%d] failed: %s", fn, sd, strerror(errno));
+	    close( sd );
+	}
+	else
+	  break; /* Success */
+
+	if (!ai) {
+	    syslog(LOG_ERR, "%s: connect() failed to all addresses.", fn);
+	    sleep( 15 );    /* IMAP server may not be started yet. */
+	    ai = ISD.ai;
+	}
+    }
+    memcpy( &ISD.srv, ai->ai_addr, addrlen );
+    
+#else
     for ( ;; )
     {
 	sd = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP );
@@ -977,9 +1081,10 @@
 	    
 	    sleep( 15 );    /* IMAP server may not be started yet. */
 	}
+	else 
 	break;  /* Success */
     }
-    
+#endif    
     
     memset( &conn, 0, sizeof ( ICD_Struct ) );
     itd.conn = &conn;
only in patch2:
--- up-imapproxy-1.2.4.orig/include/imapproxy.h
+++ up-imapproxy-1.2.4/include/imapproxy.h
@@ -190,2 +190,6 @@
 {
+#ifdef HAVE_IPV6
+    struct addrinfo *ai;
+    struct sockaddr_storage srv;     /* IMAP socket address                */
+#else
     struct hostent host;             /* IMAP host entry                    */
@@ -193,2 +197,3 @@
     struct sockaddr_in srv;          /* IMAP socket address                */
+#endif
 };
@@ -264,3 +269,7 @@
     char *server_hostname;                    /* server we proxy to */
+#ifdef HAVE_IPV6
+    char *server_port;                        /* getaddrinfo() wants a string and then we can use service names */
+#else
     unsigned int server_port;                 /* port we proxy to */
+#endif
     unsigned int cache_size;                  /* number of cache slots */
only in patch2:
--- up-imapproxy-1.2.4.orig/src/config.c
+++ up-imapproxy-1.2.4/src/config.c
@@ -368,4 +368,9 @@
 
+#ifdef HAVE_IPV6
+    ADD_TO_TABLE( "server_port", SetStringValue, 
+		  &PC_Struct.server_port, index );
+#else
     ADD_TO_TABLE( "server_port", SetNumericValue, 
 		  &PC_Struct.server_port, index );
+#endif
 
only in patch2:
--- up-imapproxy-1.2.4.orig/configure.in
+++ up-imapproxy-1.2.4/configure.in
@@ -34,2 +34,9 @@
 
+AC_ARG_ENABLE(ipv6, [  --enable-ipv6           enable IPv6 support (default)],
+        if test x$enableval = xno; then
+                want_ipv6=no
+        else
+                want_ipv6=yes
+        fi,
+        want_ipv6=yes)
 
@@ -131,2 +138,20 @@
 
+if test "x$want_ipv6" = "xyes"; then
+        AC_MSG_CHECKING([for IPv6])
+        AC_CACHE_VAL(i_cv_type_in6_addr,
+        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+        #include <sys/types.h>
+        #include <sys/socket.h>
+        #include <netinet/in.h>
+        #include <netdb.h>
+        #include <arpa/inet.h>]],
+        [[struct in6_addr i;]])],
+        [i_cv_type_in6_addr=yes],
+        [i_cv_type_in6_addr=no])])
+        if test $i_cv_type_in6_addr = yes; then
+                AC_DEFINE(HAVE_IPV6,, Build with IPv6 support)
+        fi
+        AC_MSG_RESULT($i_cv_type_in6_addr)
+fi
+
 

Attachment: pgpagXn4f83Vr.pgp
Description: PGP signature


--- End Message ---
--- Begin Message ---
Source: up-imapproxy
Source-Version: 1.2.4-5

We believe that the bug you reported is fixed in the latest version of
up-imapproxy, which is due to be installed in the Debian FTP archive:

imapproxy_1.2.4-5_i386.deb
  to pool/main/u/up-imapproxy/imapproxy_1.2.4-5_i386.deb
up-imapproxy_1.2.4-5.diff.gz
  to pool/main/u/up-imapproxy/up-imapproxy_1.2.4-5.diff.gz
up-imapproxy_1.2.4-5.dsc
  to pool/main/u/up-imapproxy/up-imapproxy_1.2.4-5.dsc



A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [EMAIL PROTECTED],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Jose Luis Tallon <[EMAIL PROTECTED]> (supplier of updated up-imapproxy package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [EMAIL PROTECTED])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Format: 1.7
Date: Wed, 20 Sep 2006 23:10:36 +0200
Source: up-imapproxy
Binary: imapproxy
Architecture: source i386
Version: 1.2.4-5
Distribution: unstable
Urgency: high
Maintainer: Jose Luis Tallon <[EMAIL PROTECTED]>
Changed-By: Jose Luis Tallon <[EMAIL PROTECTED]>
Description: 
 imapproxy  - IMAP protocol proxy
Closes: 333847 339752 370022 375665 381663 388500
Changes: 
 up-imapproxy (1.2.4-5) unstable; urgency=high
 .
   * Code enhancements
     - Change priority of 'peer verify' messages to LOG_INFO (Closes: #339752)
     - Fixed typo in src/main.c (Closes: #388500)
 .
   * IPv6 support added (Closes: #370022)
 .
   * Localization:
     - pt translation added (Closes: #381663)
 .
   * Init.d infrastructure
     - Added /etc/default/imapproxy support (Closes: #375665)
     - Reduce initscript's verbosity again (Closes: #333847)
Files: 
 0af98709f0787c22af3e74e756e8d983 671 mail optional up-imapproxy_1.2.4-5.dsc
 ad68dd2258255ac6ef87165f518390e9 131331 mail optional 
up-imapproxy_1.2.4.orig.tar.gz
 502d08b2c284f962c43ae50b0a8a0252 14077 mail optional 
up-imapproxy_1.2.4-5.diff.gz
 fe00dc62221c9ed27f933e595586fbe1 51658 mail optional imapproxy_1.2.4-5_i386.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (GNU/Linux)

iD8DBQFFE6gnNFDtUT/MKpARAhwDAKCzMYGD+5kLdG1Rz5o699ZylG7CzQCfSiJI
qANJY6oJOPgziDmtinjuE3A=
=KnAT
-----END PGP SIGNATURE-----


--- End Message ---

Reply via email to