Re: [Dnsmasq-discuss] Is dnsmasq supposed to listen on UDP port 0.0.0.0:67 when listen-address is specified?

2017-12-22 Thread Ignat Korchagin
I think so as well. It may create issues when someone runs 2 dnsmasq
processes with different configurations (for different interfaces for
example - 1 dnsmasq process per interface). Kernel may "balance" incoming
UDP packets to another dnsmasq instance (which AFAIR will just ignore it),
so there will be more retries in general for DHCP traffic.

On Fri, Dec 22, 2017 at 2:46 AM, Parke  wrote:

> On Thu, Dec 21, 2017 at 2:56 AM, Ignat Korchagin 
> wrote:
> > FYI a good overview of SO_REUSEPORT at least in Linux is here
> > https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/
>
> Thanks.  The article deals with accepting on a TCP socket, not
> receiving on a UDP socket.
>
> But if the principles are similar for UDP, then, as I expected, it
> looks like SO_REUSEPORT provides load balancing.
>
> Does anyone believe that dnsmasq is intending to create load balancing
> when multiple instances bind to the same DHCP socket?  (I don't.  I
> believe dnsmasq is expecting mirroring, but I could be wrong.)
>
> Cheers,
>
> Parke
>
> ___
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss@lists.thekelleys.org.uk
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
>
___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] Is dnsmasq supposed to listen on UDP port 0.0.0.0:67 when listen-address is specified?

2017-12-21 Thread Parke
On Thu, Dec 21, 2017 at 2:56 AM, Ignat Korchagin  wrote:
> FYI a good overview of SO_REUSEPORT at least in Linux is here
> https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/

Thanks.  The article deals with accepting on a TCP socket, not
receiving on a UDP socket.

But if the principles are similar for UDP, then, as I expected, it
looks like SO_REUSEPORT provides load balancing.

Does anyone believe that dnsmasq is intending to create load balancing
when multiple instances bind to the same DHCP socket?  (I don't.  I
believe dnsmasq is expecting mirroring, but I could be wrong.)

Cheers,

Parke

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] Is dnsmasq supposed to listen on UDP port 0.0.0.0:67 when listen-address is specified?

2017-12-21 Thread Ignat Korchagin
FYI a good overview of SO_REUSEPORT at least in Linux is here
https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/

On Thu, Dec 21, 2017 at 5:45 AM, Parke  wrote:

> On Wed, Dec 20, 2017 at 9:18 PM, Parke  wrote:
> > And there is the big question of: Will each incoming UDP packet be
> > sent to all receiving sockets?  Or just to one out of a pool of
> > receiving sockets?
>
> Looks like load balancing to me.
>
> From man 7 socket on Linux:
>
>SO_REUSEPORT (since Linux 3.9)
>
>   For UDP sockets, the use of this option  can
>   provide   better  distribution  of  incoming
>   datagrams to multiple processes (or threads)
>   as  compared to the traditional technique of
>   having multiple processes compete to receive
>   datagrams on the same socket.
>
> Perhaps dnsmasq is hoping that each separate instance is bound to a
> different device/interface via SO_BINDTODEVICE?  (Of course, dnsmasq
> lacks the ability to confirm that other instances are correctly
> configured.)
>
> And that device binding will give each incoming packet only a single
> path to the single (and correct) instance of dnsmasq?
>
> And the SO_REUSEADDR option is necessary to allow multiple bindings to
> the same address (even though each binding is to a separate interface
> via SO_BINDTODEVICE)?
>
> And given that FreeBSD lacks SO_BINDTODEVICE, this code will not work
> as intended on FreeBSD?  (I.e. FreeBSD will get undesired load
> balancing, rather than mirroring which would work?)
>
> But it seems that all the above can be done with just SO_REUSEADDR,
> and that SO_REUSEPORT is superfluous.  At least on Linux.  (As the
> purpose of SO_REUSEPORT is to load balance across processes while
> bypassing expensive inter-process contention for a single socket?)
> Hmmm.  Hopefully someone who understands it can decide if I am making
> any sense.
>
> -Parke
>
> ___
> Dnsmasq-discuss mailing list
> Dnsmasq-discuss@lists.thekelleys.org.uk
> http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss
>
___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] Is dnsmasq supposed to listen on UDP port 0.0.0.0:67 when listen-address is specified?

2017-12-20 Thread Parke
On Wed, Dec 20, 2017 at 9:18 PM, Parke  wrote:
> And there is the big question of: Will each incoming UDP packet be
> sent to all receiving sockets?  Or just to one out of a pool of
> receiving sockets?

Looks like load balancing to me.

>From man 7 socket on Linux:

   SO_REUSEPORT (since Linux 3.9)

  For UDP sockets, the use of this option  can
  provide   better  distribution  of  incoming
  datagrams to multiple processes (or threads)
  as  compared to the traditional technique of
  having multiple processes compete to receive
  datagrams on the same socket.

Perhaps dnsmasq is hoping that each separate instance is bound to a
different device/interface via SO_BINDTODEVICE?  (Of course, dnsmasq
lacks the ability to confirm that other instances are correctly
configured.)

And that device binding will give each incoming packet only a single
path to the single (and correct) instance of dnsmasq?

And the SO_REUSEADDR option is necessary to allow multiple bindings to
the same address (even though each binding is to a separate interface
via SO_BINDTODEVICE)?

And given that FreeBSD lacks SO_BINDTODEVICE, this code will not work
as intended on FreeBSD?  (I.e. FreeBSD will get undesired load
balancing, rather than mirroring which would work?)

But it seems that all the above can be done with just SO_REUSEADDR,
and that SO_REUSEPORT is superfluous.  At least on Linux.  (As the
purpose of SO_REUSEPORT is to load balance across processes while
bypassing expensive inter-process contention for a single socket?)
Hmmm.  Hopefully someone who understands it can decide if I am making
any sense.

-Parke

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] Is dnsmasq supposed to listen on UDP port 0.0.0.0:67 when listen-address is specified?

2017-12-20 Thread Parke
On Wed, Dec 20, 2017 at 7:47 PM, Kurt H Maier  wrote:
> If I understand this right, I think I can replicate it with e.g.
>
> dnsmasq --interface=eth0 \
> --dhcp-range=192.168.0.50,192.168.0.100,12h \
> --bind-interfaces \
> --listen-address=192.168.1.50

In terms of DNS on port 53:

--listen-address=192.168.1.50 will bind to 1 IPv4 address (and is
equivalent to my test.conf file).

--interface=eth0 will bind to 2 IPv4 addresses and 2 IPv6 addresses.
The second IPv4 and second IPv6 addresses are the localhost addresses.

> In this case, we can trace this to get:
> setsockopt(4, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
> setsockopt(4, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0
> setsockopt(4, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
> bind(4, {sa_family=AF_INET, sin_port=htons(67), 
> sin_addr=inet_addr("0.0.0.0")}, 16) = 0
> ...
> setsockopt(4, SOL_SOCKET, SO_BINDTODEVICE, "eth0\0\0\0\0\0\0\0\0\0\0\0\0", 
> 16) = 0
>
> So, while SO_REUSEPORT and SO_REUSEADDR are both successful, I'm not
> able to create another socket to listen (dnsmasq fails with the address
> already in use error).

Well, it could be trying to bind twice to 192.168.1.50:53 (for DNS).
That could fail - those bindings might to be set to SO_REUSEPORT.

I am not trying to run two copies of dnsmasq.  I just noticed that
dnsmasq was binding to 0.0.0.0:67, which I thought was strange, given
that I had specified a listen address.



Okay, so here is the code.

http://thekelleys.org.uk/gitweb/?p=dnsmasq.git;a=blob;f=src/dhcp.c;h=4a2983e79cf0143ddc0789014ba0582c1f47e6e9;hb=HEAD#l95

Interesting, I did not know about the "new" (as of Linux 3.9) option
of SO_REUSEPORT.

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=c617f398edd4db2b8567a28e899a88f8f574798d

>From the above kernel.org link:



This series implements so_reuseport (SO_REUSEPORT socket option) for
TCP and UDP.  For TCP, so_reuseport allows multiple listener sockets
to be bound to the same port.  In the case of UDP, so_reuseport allows
multiple sockets to bind to the same port.  To prevent port hijacking
all sockets bound to the same port using so_reuseport must have the
same uid.  Received packets are distributed to multiple sockets bound
to the same port using a 4-tuple hash.

[snip]

The motivating case for so_reuseport in UDP would be something like a
DNS server.  An alternative would be to recv on the same socket from
multiple threads.  As in the case of TCP, the load across these threads
tends to be disproportionate and we also see a lot of contection on
the socket lock.  Note that SO_REUSEADDR already allows multiple UDP
sockets to bind to the same port, however there is no provision to
prevent hijacking and nothing to distribute packets across all the
sockets sharing the same bound port.  This patch does not change the
semantics of SO_REUSEADDR, but provides usable functionality of it
for unicast.



Hmmm.

"Received [UDP] packets are distributed to multiple sockets bound to
the same port using a 4-tuple hash."

I wonder what the above means?  It sounds like load balancing, not
full delivery of each datagram to all sockets.

>From the FreeBSD man page:

https://www.freebsd.org/cgi/man.cgi?query=setsockopt

SO_REUSEADDR indicates that the rules used in validating addresses
supplied in a bind(2) system call should allow reuse of local
addresses.

SO_REUSEPORT allows completely duplicate bindings by multiple
processes if they all set SO_REUSEPORT before binding the port.  This
option permits multiple instances of a program to each receive UDP/IP
multicast or broadcast datagrams destined for the bound port.



Hmmm.

"This option permits multiple instances of a program to each receive
UDP/IP multicast or broadcast datagrams destined for the bound port."

But will each program receive each and every datagram?  (Which is what
I believe dnsmasq is expecting.)

In any case...

It does appear that binding to 0.0.0.0:67 is the intended behavior.
(I was unaware that multiple processes could bind to and read from the
same UDP socket.)

I suppose it is possible that binding to 0.0.0.0 is necessary to
receive DHCP packets.  I lack experience with the mechanics of DHCP,
and with UDP broadcast packets, so I cannot say.

And there is the big question of: Will each incoming UDP packet be
sent to all receiving sockets?  Or just to one out of a pool of
receiving sockets?

-Parke

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss


Re: [Dnsmasq-discuss] Is dnsmasq supposed to listen on UDP port 0.0.0.0:67 when listen-address is specified?

2017-12-20 Thread Kurt H Maier
On Wed, Dec 20, 2017 at 06:40:10PM -0800, Parke wrote:
> Hi,
> 
> Here is a minimal, three line test.conf file:

If I understand this right, I think I can replicate it with e.g.

dnsmasq --interface=eth0 \
--dhcp-range=192.168.0.50,192.168.0.100,12h \
--bind-interfaces \
--listen-address=192.168.1.50

In this case, we can trace this to get:
setsockopt(4, SOL_SOCKET, SO_BROADCAST, [1], 4) = 0
setsockopt(4, SOL_SOCKET, SO_REUSEPORT, [1], 4) = 0
setsockopt(4, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
bind(4, {sa_family=AF_INET, sin_port=htons(67), sin_addr=inet_addr("0.0.0.0")}, 
16) = 0
...
setsockopt(4, SOL_SOCKET, SO_BINDTODEVICE, "eth0\0\0\0\0\0\0\0\0\0\0\0\0", 16) 
= 0

So, while SO_REUSEPORT and SO_REUSEADDR are both successful, I'm not
able to create another socket to listen (dnsmasq fails with the address
already in use error).

khm

___
Dnsmasq-discuss mailing list
Dnsmasq-discuss@lists.thekelleys.org.uk
http://lists.thekelleys.org.uk/mailman/listinfo/dnsmasq-discuss