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;