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; }