Greg Troxel
2023-Aug-05 12:24 UTC
[Nut-upsdev] [Nut-upsuser] Question on simultaneous IPv4 and IPv6 "any address" listening
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
Jim Klimov
2023-Aug-06 12:32 UTC
[Nut-upsdev] [Nut-upsuser] Question on simultaneous IPv4 and IPv6 "any address" listening
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-upsdev/attachments/20230806/71d131e3/attachment.htm>
Seemingly Similar Threads
- Question on simultaneous IPv4 and IPv6 "any address" listening
- Question on simultaneous IPv4 and IPv6 "any address" listening
- Question on simultaneous IPv4 and IPv6 "any address" listening
- Question on simultaneous IPv4 and IPv6 "any address" listening
- Question on simultaneous IPv4 and IPv6 "any address" listening