Download raw body.
"family inet[46]" and numeric address for getaddrinfo()
Hello,
On Tue, 16 Sep 2025 13:27:36 +0200
Florian Obser <florian@openbsd.org> wrote:
> Coming back to an old email.
>
> On 2025-03-07 09:43 +09, YASUOKA Masahiko <yasuoka@openbsd.org> 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.
"family inet[46]" and numeric address for getaddrinfo()