backend_connect source address and config_servername

Bron Gondwana brong at fastmail.fm
Mon Mar 6 18:02:22 EST 2006


On Mon, Mar 06, 2006 at 02:54:12PM -0500, Ken Murchison wrote:
> Bron Gondwana wrote:
> >Hi,
> >
> >I'm working on setting up replication for our (FastMail.FM) new servers.
> >
> >One issue I've run in to is that our machines are set up as follows:
> >
> >10.*: imap<$n>.internal
> >66.111.4.*: imap<$n>.messagingengine.com
> >
> >Now we can argue all we like about whether the IMAP servers should have
> >an external network connection at all (it's pretty heavily firewalled,
> >but for various hysterical reasons I can't cut their direct outside
> >connection just yet.
> >
> >So - I'd very much prefer config_servername to contain
> >imap<$n>.messagingengine.com since that's what the world sees on the
> >connection string - but when I do that, backend_connect binds the
> >_source_ of its TCP connections to the external IP address, despite
> >being asked to make a connection to another 10.* address.
> 
> Are you saying that you have sync_host set to imap<$n>.internal, but 
> sync_client is connecting to imap<$n>.messagingengine.com?

With some real names and numbers:

imap5 is the master, imap6 is the replica.

all_machines:/etc/hosts
10.xxx.yyy.15 imap5.internal
10.xxx.yyy.16 imap6.internal
66.111.4.15   imap5.messagingengine.com
66.111.4.16   imap6.messagingengine.com

imap5:/etc/imapd-master.conf (we will have a master and a replica on each host)
sync_host: imap6.internal

When I run sync_client, it binds the socket to 66.111.4.15, which is
then firewalled from making connections to 10.xxx.yyy.16 because the
source IP is not on the internal network.

cyrus-2.3.3/imap/backend.c:321
        /* 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));
        }

cyrus-2.3.3/imap/backend.c:343
        /* 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;


You can see here that it binds to the interface with the same name as
the server's hostname (imap5.messagingengine.com) rather than leaving
the source IP unbound.  It looks like it would be possible to give it
a name that doesn't have an interface and it would not bind to anything,
but would always log a "getaddrinfo(%s) failed: %s".  That also is
suboptimal.

Bron.


More information about the Info-cyrus mailing list