Package: nullmailer
Version: 1:1.03-5
Severity: normal
Tags: patch

Hi,

I was the person who a long while back submitted the patch for nullmailer to
have IPv6 support. I have found a minor bug in the patch I submitted, this I
noticed whilst I was adding support in a similar manner to 'ii'.

Anyway the problem is that the following lines need to be changed from:

===
if(connect(s, res->ai_addr, res->ai_addrlen) != 0)
  continue;
===

to

===
if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
  s = -1;
  continue; 
}
===

Without doing this, if nullmailer fails to connect to the SMTP server (say a
connection refused or timed out) then the section of code continues as if
there was nothing wrong, as the 'if(s < 0)' check is skipped; as the socket()
part of the function typically succeeds.

Anyway, if connect() fails then my tweak sets 's' to -1 so that the section
can break out early, rather than the error being thrown up later on in
nullmailer when she tries to send data to a closed socket.

Its a tidying up patch :)  I have attached a replacement IPv6 patch,
alternatively you can just mannually make the above adjustment to
lib/tcpconnect.cc yourself as that is all that I have changed.

Cheers

Alex

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)

Kernel: Linux 2.6.22-cfs-v19-hrt3
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages nullmailer depends on:
ii  debconf [debconf-2.0]         1.5.13     Debian configuration management sy
ii  libc6                         2.6-2      GNU C Library: Shared libraries
ii  libgcc1                       1:4.2.1-0  GCC support library
ii  libstdc++6                    4.2.1-0    The GNU Standard C++ Library v3
ii  lsb-base                      3.1-23.1   Linux Standard Base 3.1 init scrip

Versions of packages nullmailer recommends:
ii  syslog-ng [system-log-daemon] 2.0.0-1    Next generation logging daemon

-- debconf information excluded
diff -u -d -r nullmailer-1.03.orig/configure.in nullmailer-1.03/configure.in
--- nullmailer-1.03.orig/configure.in	2007-07-22 14:18:18.245274645 +0100
+++ nullmailer-1.03/configure.in	2007-07-22 14:18:52.240088523 +0100
@@ -47,6 +47,24 @@
 dnl AC_CHECK_FUNCS(gettimeofday mkdir putenv rmdir socket)
 AC_CHECK_FUNCS(setenv srandom)
 
+AC_MSG_CHECKING(for getaddrinfo)
+AC_TRY_COMPILE([#include <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>], [getaddrinfo(NULL, NULL, NULL, NULL)], has_getaddrinfo=yes, has_getaddrinfo=no)
+if test "$has_getaddrinfo" = yes; then
+  AC_MSG_RESULT(yes)
+else
+  AC_MSG_RESULT(no)
+fi
+
+if test x-$has_getaddrinfo = "x-no" ; then
+  AC_MSG_RESULT(disabled: getaddrinfo missing)
+else
+  AC_DEFINE(HAVE_GETADDRINFO,,[getaddrinfo code enabled])
+fi
+
+AC_SUBST(HAVE_GETADDRINFO)
+
 AC_DEFINE(BUFSIZE, 4096, [Generic buffer size])
 AM_CONDITIONAL(FDBUF_NO_MYSTRING, false)
 
Only in nullmailer-1.03/debian: patched
diff -u -d -r nullmailer-1.03.orig/lib/tcpconnect.cc nullmailer-1.03/lib/tcpconnect.cc
--- nullmailer-1.03.orig/lib/tcpconnect.cc	2007-07-22 14:18:18.245274645 +0100
+++ nullmailer-1.03/lib/tcpconnect.cc	2007-07-22 14:19:20.735741332 +0100
@@ -28,7 +28,11 @@
 #include <netinet/in.h>
 #include "errcodes.h"
 #include "connect.h"
+#ifdef HAVE_GETADDRINFO
+#include "lib/itoa.h"
+#endif
 
+#ifndef HAVE_GETADDRINFO
 static int sethostbyname(const mystring& hostname, struct sockaddr_in& sa)
 {
   struct hostent *he = gethostbyname(hostname.c_str());
@@ -44,13 +48,48 @@
   memcpy(&sa.sin_addr, he->h_addr, he->h_length);
   return 0;
 }
+#endif
 
 int tcpconnect(const mystring& hostname, int port)
 {
+#ifdef HAVE_GETADDRINFO
+  struct addrinfo req, *res, *orig_res;
+  const char *service = itoa(port, 6);
+  
+  memset(&req, 0, sizeof(req));
+  req.ai_flags = AI_NUMERICSERV;
+  req.ai_socktype = SOCK_STREAM;
+  int e = getaddrinfo(hostname.c_str(), service, &req, &res);
+#else
   struct sockaddr_in sa;
   memset(&sa, 0, sizeof(sa));
   int e = sethostbyname(hostname, sa);
+#endif
   if(e) return e;
+#ifdef HAVE_GETADDRINFO
+  int s;
+  orig_res = res;
+
+  for (; res; res = res->ai_next ) {
+    s = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+
+    if(s < 0)
+	continue;
+
+    if(connect(s, res->ai_addr, res->ai_addrlen) != 0) {
+    	s = -1;
+	continue;
+    }
+
+    /* sucessful connection */
+    break;
+  }
+
+  freeaddrinfo(orig_res);
+
+  if(s < 0)
+    return -ERR_CONN_FAILED;
+#else
   sa.sin_family = AF_INET;
   sa.sin_port = htons(port);
   int s = socket(PF_INET, SOCK_STREAM, 0);
@@ -64,5 +103,6 @@
     default: return -ERR_CONN_FAILED;
     }
   }
+#endif
   return s;
 }

Reply via email to