From: YASUOKA Masahiko Subject: Re: "family inet[46]" and numeric address for getaddrinfo() To: florian@openbsd.org Cc: tech@openbsd.org Date: Wed, 17 Sep 2025 12:00:09 +0900 Hello, On Tue, 16 Sep 2025 13:27:36 +0200 Florian Obser wrote: > 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. You are correct. I missed the behaviour of _asr_sockaddr_from_str. > OK? ok yasuoka > > 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.