Dear all,

I'm submitting a patch which fixes a slightly irritating (although not
serious) problem, whereby the Cyrus Murder daemons proxyd and lmtpproxyd
do not bind to the correct interface when opening tcp connections to the
backend servers. This happens when the servername of the Murder
front-end is not the primary interface on the host. This leads to
inconsistent Cyrus logs and Received headers on delivered mail.

The patch simply adds a bind() call to the backend_connect() function of
imap/backend.c. It tries to bind the socket to the interface specified
by the servername imapd.conf option.

I'd be grateful if someone could take a look at this. It should patch OK
against the CVS HEAD.

Regards,
Stephen Grier

-- 

Stephen Grier
Systems Developer
Computing Services
Queen Mary, University of London



diff -Naur cyrus-imapd-2.2.10.old/imap/backend.c cyrus-imapd-2.2.10/imap/backend.c
--- cyrus-imapd-2.2.10.old/imap/backend.c	2004-10-27 17:53:35.000000000 +0100
+++ cyrus-imapd-2.2.10/imap/backend.c	2005-02-24 14:39:46.542462000 +0000
@@ -272,7 +272,7 @@
     int sock = -1;
     int r;
     int err;
-    struct addrinfo hints, *res0 = NULL, *res;
+    struct addrinfo hints, *res0 = NULL, *res1 = NULL, *res;
     struct sockaddr_un sunsock;
     char buf[2048], *mechlist = NULL;
     struct sigaction action;
@@ -315,6 +315,12 @@
 	    free(ret);
 	    return NULL;
 	}
+        /* Get addrinfo struct for local interface. */
+        err = getaddrinfo(config_servername, NULL, &hints, &res1);
+        if(err) {
+            syslog(LOG_ERR, "getaddrinfo(%s) failed: %s",
+                   config_servername, gai_strerror(err));
+        }
     }
 
     /* Setup timeout */
@@ -331,6 +337,15 @@
 	sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
 	if (sock < 0)
 	    continue;
+        /* Bind to local interface. */
+        if (!err) {
+            if (bind(sock, res1->ai_addr, res1->ai_addrlen) < 0) {
+                struct sockaddr_in *local_sockaddr = (struct sockaddr_in *) res1->ai_addr;
+                syslog(LOG_ERR, "failed to bind to address %s: %s",
+                       inet_ntoa(local_sockaddr->sin_addr), strerror(errno));
+            }
+            freeaddrinfo(res1);
+        }
 	alarm(config_getint(IMAPOPT_CLIENT_TIMEOUT));
 	if (connect(sock, res->ai_addr, res->ai_addrlen) >= 0)
 	    break;

Reply via email to