[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-ID: <20130316055632.GA21364@wilbur.25thandClement.com>
Date: Fri, 15 Mar 2013 22:56:32 -0700
From: William Ahern <william@...handClement.com>
To: netdev@...r.kernel.org
Subject: connect(2) reassociation regression
I've stumbled upon what may be a regression in connect(2) behavior.
My DNS library uses connect(2) to reassociate UDP sockets. That way the
kernel can filter my packets, and it makes for cleaner code overall. The
Linux manual page makes it pretty clear that this is okay, and at least one
interpretation of POSIX (certainly the one I had) does as well.
At some point in the 3.x cycle (maybe after 3.2.0) something was changed.
Whereas previously any reassociation worked, regardless of destination
network, now if the _first_ association is to the loopback, any subsequent
association to non-loopback fails with EINVAL. However, if the loopback is
the second or later association then everything continues to work. In other
words, the sequence
connect(127.0.0.1), connect(8.8.8.8)
fails with EINVAL, but
connect(8.8.8.8), connect(127.0.0.1), connect(1.2.3.4)
succeeds.
I admit that originally I simply presumed that on each reassociation the
kernel would handle reassociating the source address in addition to the
destination address. The technique worked everywhere I tested, including
Linux, Solaris, NetBSD, OpenBSD, FreeBSD. And I should note that it even
worked when reassociating to different external networks (and still works on
everything but Linux, AFAICT).
I realize now that arguably POSIX only requires that a second connnect call
change the destination address, and not the source address. But what would
be the point of allowing a reassociation if the source address is never
changed? Because any two addresses may route to entirely different networks
or over different devices, the capability to reassociate would be pointless.
OTOH, if you explicitly called bind before connect, most systems these days
will unbind the source address when reassociating. That may be undesirable
behavior, but it is long-standing behavior AFAICT, including on Linux. One
way to bypass the new Linux behavior is to reset the socket with
connect(AF_UNSPEC), but under the pedantic interpretation of POSIX that's
not guaranteed to work.
I first posted this issue on comp.unix.programmer, including example code.
The thread is at
https://groups.google.com/forum/?fromgroups=#!topic/comp.unix.programmer/ya0V-rr8ip0
Although it's hard to follow w/ Google's horrendous interface.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists