From: Florian Obser Subject: Re: "family inet[46]" and numeric address for getaddrinfo() To: YASUOKA Masahiko Cc: tech@openbsd.org Date: Tue, 16 Sep 2025 13:27:36 +0200 Coming back to an old email. On 2025-03-07 09:43 +09, YASUOKA Masahiko wrote: > Hello, > > sshd's config has the following default values, > > #AddressFamily any > #ListenAddress 0.0.0.0 > #ListenAddress :: > > If we configure "family" in /etc/resolv.conf, sshd will stop listening > 0.0.0.0 or :: following the "family" config. > > - "family inet4" => stop listening on :: > - "family inet6" => stop listening on 0.0.0.0 > > This is because getaddrinfo() doesn't convert a numeric address if the > family is disabled and NI_NUMERIC_HOST is not specified. > > I don't think this is correct behavior. I don't think this is correct behaviour either. I *think* your diff is correct, but it's complicated, this is easier: 1. if hints.ai_family == AF_UNSPEC, _asr_sockaddr_from_str tries all (both) AFs in sequence for us. 2. if hints.ai_family != AF_UNSPEC, _asr_sockaddr_from_str validates that the hostname is a correct address in the specified family. Therefore, we can just pass in hints.ai_family and it will do the right thing. OK? diff --git lib/libc/asr/getaddrinfo_async.c lib/libc/asr/getaddrinfo_async.c index 46245831f12..3ab92fc903c 100644 --- lib/libc/asr/getaddrinfo_async.c +++ lib/libc/asr/getaddrinfo_async.c @@ -272,17 +272,10 @@ getaddrinfo_async_run(struct asr_query *as, struct asr_result *ar) } /* Try numeric addresses first */ - for (family = iter_family(as, 1); - family != -1; - family = iter_family(as, 0)) { - - if (_asr_sockaddr_from_str(&sa.sa, family, - as->as.ai.hostname) == -1) - continue; - + if (_asr_sockaddr_from_str(&sa.sa, ai->ai_family, + as->as.ai.hostname) != -1) { if ((r = addrinfo_add(as, &sa.sa, as->as.ai.hostname))) ar->ar_gai_errno = r; - break; } if (ar->ar_gai_errno || as->as_count) { async_set_state(as, ASR_STATE_HALT); > > When a numeric address is given, I suppose it's expected that the > numeric address can be converted into an address object without a name > resolution. (it's resolved from the beginning) Therefore any config > in resolv.conf should not effect the result. > > I checked that our previous resolver (on 5.2, before asr) behaves as I > expected. > > ok? > > Index: lib/libc/asr/getaddrinfo_async.c > =================================================================== > RCS file: /cvs/src/lib/libc/asr/getaddrinfo_async.c,v > diff -u -p -r1.63 getaddrinfo_async.c > --- lib/libc/asr/getaddrinfo_async.c 21 Aug 2024 05:53:10 -0000 1.63 > +++ lib/libc/asr/getaddrinfo_async.c 7 Mar 2025 00:15:42 -0000 > @@ -58,6 +58,8 @@ static const struct match matches[] = { > { -1, 0, 0, }, > }; > > +static const int families[] = { PF_INET, PF_INET6, -1 }; > + > #define MATCH_FAMILY(a, b) ((a) == matches[(b)].family || (a) == PF_UNSPEC) > #define MATCH_PROTO(a, b) ((a) == matches[(b)].protocol || (a) == 0 || matches[(b)].protocol == 0) > /* Do not match SOCK_RAW unless explicitly specified */ > @@ -272,11 +274,12 @@ getaddrinfo_async_run(struct asr_query * > } > > /* Try numeric addresses first */ > - for (family = iter_family(as, 1); > - family != -1; > - family = iter_family(as, 0)) { > + for (i = 0; families[i] != -1; i++) { > > - if (_asr_sockaddr_from_str(&sa.sa, family, > + if (as->as.ai.hints.ai_family != PF_UNSPEC && > + as->as.ai.hints.ai_family != families[i]) > + continue; > + if (_asr_sockaddr_from_str(&sa.sa, families[i], > as->as.ai.hostname) == -1) > continue; > > -- In my defence, I have been left unsupervised.