[ntp:questions] ntpd and network sockets

Danny Mayer mayer at ntp.isc.org
Thu Jan 10 03:28:54 UTC 2008


Rick Jones wrote:
>> The -L option only looks for colons (:) in the interface name and is not 
>> a general method of dealing with "logical" interfaces. We really need to 
>> get rid of it, which is what the listen-on code will do for people.
> 
> Speaking of colons, it is unfortunate that both (logical) interface
> names, and IPv6 addresses have colons in them.  Thankfully I suppose,
> an IPv6 address will always have at least two colons and presumably an
> interface name will only have the one.  That way listen-on will be
> able to distinguish an interface name from an IPv6 address even if it
> cannot a priori distinguish between an interface and a DNS name.
> 

I'm using BIND9 code to convert addresses, so any failure is an 
interface name! :) Works well.

>>> In Security Issues, open-read-drop, it might be good to explicitly
>>> mention SO_REUSEADDR and/or SO_REUSEPORT and how they may or may not
>>> apply.
>>>
> 
>> SO_REUSADDR and/or SO_REUSEPORT are only useful if the address/port is 
>> bound to a socket. SO_REUSADDR is used in the current code.
> 
> SO_REUSEPORT is the one that allows another process to bind to the
> same port right?
> 

Right, but we don't use it anywhere in the code. We would prefer not to 
have more than one application reading from an address/port.

>>> Is there really much point in actually recving datagrams on such
>>> sockets?  Could just as easily set the SO_RCVBUF to something "really
>>> small" and then blythly ignore the socket entirely.  Yes, it means
>>> that the stacks "socket buffer overflow" stat will increase I
>>> suppose...
>>>
> 
>> The packets usually are small. 48 is the natural number of an NTP
>> packet and only gets to be large if there are extension headers, for
>> instance for autokey. The code only reads as much data as fits in
>> the buffer and then ignores the contents so you cannot really get a
>> buffer overflow.
> 
> I suspect we are thinking of different buffers.  I was talking about
> the socket buffer - aka SO_RCVBUF - overflowing if ntpd simply bound a
> socket and never read from it.  I wasn't thinking about a buffer
> overflow in the ntpd itself.  Just trying to see if ntpd could avoid
> even doing the partial read of the datagram(s) on the socket.
> 

Sorry, I missed that. Maybe you know better than me but I would not 
expect the socket buffer to allow overflow or there would be major 
problems with all O/S's since anyone can mount an attack to overflow 
that buffer. I don't know the internals of most IP stacks.

>>> WRT query-on, last query-on wins.  Otherwise you have to extend to
>>> rules to select which query-on when... 
>>>
> 
>> I didn't understand that.
> 
> That's ok I might not have also :) If there were multiple query-on
> statements and if more than one was to be "kept" as it were, then one
> has to decide when to query from which.
> 

The query-on address has to meet two criteria: 1) the address must match 
an available address on which packets are being accepted (see listen-on 
if not all are accepted) and 2) it needs to match the family of the 
address for which it needs to make the query. For IPv6 it also needs to 
ensure that if the required address is link-local or site-local then so 
too is the query-on address but not if it is not. It is intended to be 
similar to query-source in BIND9 except we have a lot more flexibility 
here. I really don't expect more than one or two addresses to be entered 
here.

>>> WRT listen-on, "*" wouldn't specify address family.  If instead it
>>> parsed 0 or 0.0.0.0 for IPv4 wildcard, or text "INADDR_ANY" or ::0 for
>>> IPv6 wildcard or whatever its macro is then it would be implicit.  I
>>> don't think you can take both interface names and DNS names as
>>> arguments because it will not be possible to distinguish one from the
>>> other.  You could prioritize one over the other - a strawman would be
>>> to match the string against interface names first before calling
>>> getaddrinfo().  
>>>
> 
>> I am aware of no application that uses DNS to store its own list of 
>> addresses and makes no sense to me.
> 
> I wasn't suggesting to use DNS to store things, just discussing issues
> if one wanted to be able to take both interface names and DNS names as
> arguments to something like listen-on.
> 
>>> If there is listen-on that means process and drop-on that means
>>> readdrop (or opensock and no read) then ntpd doesn't have to care about
>>> finding any other IP's on the system, they would be implictly
>>> "ignored"  Thus IIRC there would no longer be any need/call for ntpd to
>>> know how to enumerate all the IP's on a system and/or check that
>>> periodically.  
>>>
> 
>> You do need to know in order for Autokey to work properly.
> 
> OK.
> 
>>> Unless, of course, the wildcard IP meant that it should open a socket
>>> for each IP it finds rather than simply opening one socket bound to
>>> the wildcard address.
> 
>> We cannot do that since we need to know the IP address being used and to 
>> make sure we return packets with the same address. wildcard IP doesn't 
>> give you that control.
> 
> In theory, if one wanted to have a socket for every IP on the system,
> receipt of a message on the socket bound to the wildcard(s) could be
> used as the trigger to say "time to scan the system for IP addresses"
> You could then simply discard that message and rely on the remote to
> send another.
> 
> Of course there is still a chance that some other process could get in
> there and bind to the newly-added IP before a request arrived, and a
> request to that IP will go to the closest match and so not the
> wildcard-bound socket. Alas, there really is no (portable) way to be
> completely assured that ntpd and only ntpd will receive traffic for
> port 123 on all IPs on the local host.
> 
>>> FWIW I'd go with last wins, and process the config file as the command
>>> line is processed.  Then, any command-line args after a config file
>>> arg can override the config file, and the config file can override a
>>> previous command-line.  But then I'm probably not writing the code,
>>> just tossing things in from the peanut gallery.
>>>
>> I am troubled by that too.
> 
> I didn't mean to imply I was troubled, just pointing-out how it might
> conceivably work if one went with last-wins.
> 
> 
>>> One thing about a socket bound to a wildcard address is that it will
>>> pick-up traffic from interfaces enabled after ntpd has been started,
>>> without ntpd having to periodically scan for new IP's on the system
>>> (and possibly miss one that was only around for less than ntpd's
>>> rescan interval).
> 
> I was wrong when I first said this - there will still be a window
> where a new IP can be brought-up on the system, and some other process
> can bind port 123 to that IP before ntpd can get there or traffic to
> arrive.  Even if ntpd has a socket bound to the wildcard IP.
> 

Binding to a wildcard address does not prevent another process binding 
to a different IP address that ntpd is not bound. At least I don't 
believe so.

Danny
> rick jones




More information about the questions mailing list