[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1271161297.16881.293.camel@edumazet-laptop>
Date: Tue, 13 Apr 2010 14:21:37 +0200
From: Eric Dumazet <eric.dumazet@...il.com>
To: Michal Svoboda <michal.svoboda@...nts.felk.cvut.cz>
Cc: netdev@...r.kernel.org
Subject: Re: SO_REUSEADDR with UDP (again)
Le mardi 13 avril 2010 à 13:27 +0200, Michal Svoboda a écrit :
> Eric Dumazet wrote:
> > Why do you use REUSEADDR ? This is doing what is documented.
> >
> > SO_REUSEADDR
> > Indicates that the rules used in validating addresses supplied
> > in a bind(2) call should allow reuse of local addresses. For
> > AF_INET sockets this means that a socket may bind, except when
> > there is an active listening socket bound to the address. When
> > the listening socket is bound to INADDR_ANY with a specific
> > port then it is not possible to bind to this port for any local
> > address. Argument is an integer boolean flag.
>
> I read it 10 times but it doesn't say anything about stealing frames, or
> implementation-defined behavior in this case.
If it is not documented, it is implementation defined.
>
> > An UDP application wanting a port for its exclusive use dont set
> > REUSEADDR, or basically allows anybody to bind an udp socket to same
> > port, and potentially steal incoming frames.
>
> That's fair enough, I will talk to the developers of the "very buggy"
> applications that use this flag and ask them to reconsider.
;)
>
> > REUSEADDR is usually used when an application has several sockets bound
> > to same port, but different IP addresses (or bound to different devices)
>
> I just tried that and you can bind to different IPs without REUSEADDR.
Of course it is possible !
REUSEADDR allows following :
(Note that both sockets MUST have requested REUSEADDR=1)
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
main()
{
int sock1, sock2;
struct sockaddr_in addr;
int on = 1;
memset(&addr, 0, sizeof(addr));
addr.sin_port = htons(3444);
addr.sin_family = AF_INET;
sock1 = socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(sock1, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
addr.sin_addr.s_addr = htonl(0x7f000001);
if (bind(sock1, (struct sockaddr *)&addr, sizeof(addr)))
perror("bind1");
sock2 = socket(AF_INET, SOCK_DGRAM, 0);
setsockopt(sock2, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
addr.sin_addr.s_addr = INADDR_ANY; /* or htonl(0x7f000001); */
if (bind(sock2, (struct sockaddr *)&addr, sizeof(addr)))
perror("bind2");
}
If an application didnt specified REUSEADDR=1, then its UDP port is
private, it cannot be stolen.
Therefore, applications should not use REUSEADDR on unicast UDP, unless
it is a non security issue (for example, if it is able to react to any
new IP addresses added by the administrator on the machine, and complain
loudly if another application could bind() before itself)
REUSADDR has a meaning for multicast, but for unicast... this is hardly
useful ?
About the connect() thing, its also a fact that connected sockets have a
higher priority (they'll receive incoming frames, their score his higher
than a non connected socket, if source of the packet matches the connect
destination of course). Same thing if you play with BINDTODEVICE.
--
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