<div dir="ltr"><div>Thanks to everyone for a fruitful discussion, links and ideas.</div><div><br></div><div>The result is nearing a merge at <a href="https://github.com/networkupstools/nut/pull/2013">https://github.com/networkupstools/nut/pull/2013</a> 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).</div><div><br></div><div>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:</div><div>* try to get IPv4 "ANY", to know we can do so</div><div>* release IPv4, try to get IPv6 and then IPv4 again</div><div><br></div><div>If in the end neither socket works, declare a fatal error (could not fulfill the config requirement).</div><div>If we could get IPv4 initially, and could not after getting IPv6, do not bother - assume a dual-stack system (and log it so).</div><div><br></div><div>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 *`.</div><div>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.<br></div><div><br></div><div>Jim Klimov<br></div><div><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sat, Aug 5, 2023 at 2:24 PM Greg Troxel <<a href="mailto:gdt@lexort.com">gdt@lexort.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Jim Klimov via Nut-upsuser <<a href="mailto:nut-upsuser@alioth-lists.debian.net" target="_blank">nut-upsuser@alioth-lists.debian.net</a>> writes:<br>
<br>
>   I've recently found that at least on my test box the `LISTEN *` line had<br>
> only set up an IPv4 `0.0.0.0` listener but not an IPv6 `::0` listener for<br>
> `upsd`.<br>
<br>
Interesting.  On one system I checked, I have 4 explicit directives for<br>
127.0.0.1, ::1, and the LAN on v4/v6.  On another, I have an empty<br>
upsd.conf and it is listening:<br>
<br>
nut      upsd        1047    4* internet stream tcp <a href="http://127.0.0.1:3493" rel="noreferrer" target="_blank">127.0.0.1:3493</a><br>
nut      upsd        1047    5* internet6 stream tcp [::1]:3493<br>
<br>
> In fact, at least on a "dual-stack" system, it seems impossible to<br>
> bind to both - so depending on binding order I either lose IPv6 or lose<br>
> IPv4 directly (but have it practically as IPv4-over-IPv6).<br>
<br>
That is not intrinsic to a system that does v4 and v6.  It is about a<br>
misfeature which if turned on, when one binds to v6 also sets up a<br>
listener on v4 which connects as a mapped address.  These days, I view<br>
it as a bug for a system to be configuret hat way.  On NetBSD, from<br>
ip6(4):<br>
<br>
     IPV6_V6ONLY int *<br>
             Get or set whether only IPv6 connections can be made to this<br>
             socket.  For wildcard sockets, this can restrict connections to<br>
             IPv6 only.<br>
<br>
which is 1 on my system.<br>
<br>
>   Given that `LISTEN *` support is in fact not documented explicitly (I<br>
> think), I am inclined to define it as listening to "any" on whatever<br>
> address families are available and supported by the NUT build, and somehow<br>
> ensuring that to the best of our capability (technical puzzles exist - see<br>
> GitHub issue).<br>
<br>
It seems really obvious that * means anything, so agreed.<br>
<br>
I think it's important that the default, if there are no LISTEN<br>
directives, be "listen on all localhost addresses of all address<br>
familes".  And probably there should be a way to say that explicitly,<br>
like "LISTEN localhost".<br>
<br>
Practically, LISTEN localhost should:<br>
<br>
#ifdef v6 at compile time<br>
  open a socket and bind to [::1]:3493<br>
    error log that v6 bind failed<br>
#endif<br>
<br>
  open a socket and bind to <a href="http://127.0.0.1:3493" rel="noreferrer" target="_blank">127.0.0.1:3493</a><br>
    if error:<br>
      if there is a v6 socket:<br>
        debug log that v4 bind failed, maybe, or maybe it's a real<br>
        error?  need to figure out if v6only=0 systems some try to map<br>
        this.  The point  being not to fight os/sysadmin choice even if<br>
        misguided :-)<br>
      else:<br>
        error log that v4 bind failed<br>
<br>
and LISTEN * should<br>
<br>
#ifdef v6 at compile time<br>
  open a socket and bind to INADDR6_ANY:3493<br>
    error log that v6 bind failed<br>
#endif<br>
<br>
  open a socket and bind to INADDR_ANY:3493<br>
    if error:<br>
      if there is a v6 socket:<br>
        debug log that v4 bind failed<br>
      else:<br>
        error log that v4 bind failed<br>
<br>
<br>
<br>
<br>
>   Detailed musing and logs are posted in<br>
> <a href="https://github.com/networkupstools/nut/issues/2012" rel="noreferrer" target="_blank">https://github.com/networkupstools/nut/issues/2012</a><br>
><br>
>   Pro/Con ideas are welcome :)<br>
><br>
> Jim<br>
> _______________________________________________<br>
> Nut-upsuser mailing list<br>
> <a href="mailto:Nut-upsuser@alioth-lists.debian.net" target="_blank">Nut-upsuser@alioth-lists.debian.net</a><br>
> <a href="https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser" rel="noreferrer" target="_blank">https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser</a><br>
<br>
_______________________________________________<br>
Nut-upsuser mailing list<br>
<a href="mailto:Nut-upsuser@alioth-lists.debian.net" target="_blank">Nut-upsuser@alioth-lists.debian.net</a><br>
<a href="https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser" rel="noreferrer" target="_blank">https://alioth-lists.debian.net/cgi-bin/mailman/listinfo/nut-upsuser</a><br>
</blockquote></div>