[Nut-upsuser] Question on simultaneous IPv4 and IPv6 "any address" listening

Jim Klimov jimklimov+nut at gmail.com
Sun Aug 6 13:32:03 BST 2023


Thanks to everyone for a fruitful discussion, links and ideas.

The result is nearing a merge at
https://github.com/networkupstools/nut/pull/2013 and seems to not upset CI
on any platform, including Windows (which behaves funny WRT binding to the
same host:port as many times as you ask).

Ultimately the chosen logic is that if there was a `LISTEN * <port>` in
`upsd.conf`, the depending on CLI settings (-4/-6) or lack thereof we try
PIv4, IPv6 or both, with the bigger logic for "both" being:
* try to get IPv4 "ANY", to know we can do so
* release IPv4, try to get IPv6 and then IPv4 again

If in the end neither socket works, declare a fatal error (could not
fulfill the config requirement).
If we could get IPv4 initially, and could not after getting IPv6, do not
bother - assume a dual-stack system (and log it so).

Also as part of this change, NUT would ask (although not insist) for the
IPV6_V6ONLY socket option when preparing IPv6 connections, except when
handling `LISTEN *`.
Finally, I noticed that if some configuration hostname resolves to more
than one address, the first one bound wins and others are ignored. This
behavior was here before, the PR change just logs that this happens.

Jim Klimov


On Sat, Aug 5, 2023 at 2:24 PM Greg Troxel <gdt at lexort.com> wrote:

> Jim Klimov via Nut-upsuser <nut-upsuser at alioth-lists.debian.net> writes:
>
> >   I've recently found that at least on my test box the `LISTEN *` line
> had
> > only set up an IPv4 `0.0.0.0` listener but not an IPv6 `::0` listener for
> > `upsd`.
>
> Interesting.  On one system I checked, I have 4 explicit directives for
> 127.0.0.1, ::1, and the LAN on v4/v6.  On another, I have an empty
> upsd.conf and it is listening:
>
> nut      upsd        1047    4* internet stream tcp 127.0.0.1:3493
> nut      upsd        1047    5* internet6 stream tcp [::1]:3493
>
> > In fact, at least on a "dual-stack" system, it seems impossible to
> > bind to both - so depending on binding order I either lose IPv6 or lose
> > IPv4 directly (but have it practically as IPv4-over-IPv6).
>
> That is not intrinsic to a system that does v4 and v6.  It is about a
> misfeature which if turned on, when one binds to v6 also sets up a
> listener on v4 which connects as a mapped address.  These days, I view
> it as a bug for a system to be configuret hat way.  On NetBSD, from
> ip6(4):
>
>      IPV6_V6ONLY int *
>              Get or set whether only IPv6 connections can be made to this
>              socket.  For wildcard sockets, this can restrict connections
> to
>              IPv6 only.
>
> which is 1 on my system.
>
> >   Given that `LISTEN *` support is in fact not documented explicitly (I
> > think), I am inclined to define it as listening to "any" on whatever
> > address families are available and supported by the NUT build, and
> somehow
> > ensuring that to the best of our capability (technical puzzles exist -
> see
> > GitHub issue).
>
> It seems really obvious that * means anything, so agreed.
>
> I think it's important that the default, if there are no LISTEN
> directives, be "listen on all localhost addresses of all address
> familes".  And probably there should be a way to say that explicitly,
> like "LISTEN localhost".
>
> Practically, LISTEN localhost should:
>
> #ifdef v6 at compile time
>   open a socket and bind to [::1]:3493
>     error log that v6 bind failed
> #endif
>
>   open a socket and bind to 127.0.0.1:3493
>     if error:
>       if there is a v6 socket:
>         debug log that v4 bind failed, maybe, or maybe it's a real
>         error?  need to figure out if v6only=0 systems some try to map
>         this.  The point  being not to fight os/sysadmin choice even if
>         misguided :-)
>       else:
>         error log that v4 bind failed
>
> and LISTEN * should
>
> #ifdef v6 at compile time
>   open a socket and bind to INADDR6_ANY:3493
>     error log that v6 bind failed
> #endif
>
>   open a socket and bind to INADDR_ANY:3493
>     if error:
>       if there is a v6 socket:
>         debug log that v4 bind failed
>       else:
>         error log that v4 bind failed
>
>
>
>
> >   Detailed musing and logs are posted in
> > https://github.com/networkupstools/nut/issues/2012
> >
> >   Pro/Con ideas are welcome :)
> >
> > Jim
> > _______________________________________________
> > Nut-upsuser mailing list
> > Nut-upsuser at alioth-lists.debian.net
> > https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser
>
> _______________________________________________
> Nut-upsuser mailing list
> Nut-upsuser at alioth-lists.debian.net
> https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/nut-upsuser/attachments/20230806/71d131e3/attachment-0003.htm>


More information about the Nut-upsuser mailing list