Netdev List
 help / color / mirror / Atom feed
* connect(2) reassociation regression
@ 2013-03-16  5:56 William Ahern
  2013-03-16 14:51 ` Eric Dumazet
  0 siblings, 1 reply; 3+ messages in thread
From: William Ahern @ 2013-03-16  5:56 UTC (permalink / raw)
  To: netdev

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.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2013-03-16 20:40 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-16  5:56 connect(2) reassociation regression William Ahern
2013-03-16 14:51 ` Eric Dumazet
2013-03-16 20:39   ` William Ahern

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox