|
Message-ID: <20220921154134.GT9709@brightrain.aerifal.cx> Date: Wed, 21 Sep 2022 11:41:34 -0400 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Re: EAI_NODATA in musl On Mon, Sep 19, 2022 at 07:31:04PM -0400, Rich Felker wrote: > On Mon, Sep 19, 2022 at 06:26:07PM -0400, Rich Felker wrote: > > [...] > > > > Some details to work out: > > > > 1. getaddrinfo errors out with EAI_NONAME early when AI_ADDRCONFIG > > finds that the requested address family is not configured. The > > logic here probably needs to be changed to still perform a lookup > > but suppress the results if all requested families were precluded > > by AI_ADDRCONFIG. > > > > 2. gethostbyname* need to process EAI_NODATA and convert to (already > > existing) NO_DATA. > > > > 3. There was one other point where EAI_NONAME appeared in > > lookup_name.c but it was wrong and just fixed by 1e7fb12f77. > > > > Anything else? > > Updated patch attached addressing the above. > diff --git a/include/netdb.h b/include/netdb.h > index d096c781..3af065e2 100644 > --- a/include/netdb.h > +++ b/include/netdb.h > @@ -44,6 +44,7 @@ struct addrinfo { > #define EAI_NONAME -2 > #define EAI_AGAIN -3 > #define EAI_FAIL -4 > +#define EAI_NODATA -5 > #define EAI_FAMILY -6 > #define EAI_SOCKTYPE -7 > #define EAI_SERVICE -8 > diff --git a/src/network/gai_strerror.c b/src/network/gai_strerror.c > index 9596580e..56b71503 100644 > --- a/src/network/gai_strerror.c > +++ b/src/network/gai_strerror.c > @@ -6,7 +6,7 @@ static const char msgs[] = > "Name does not resolve\0" > "Try again\0" > "Non-recoverable error\0" > - "Unknown error\0" > + "Name has no usable address\0" > "Unrecognized address family or invalid length\0" > "Unrecognized socket type\0" > "Unrecognized service\0" > diff --git a/src/network/getaddrinfo.c b/src/network/getaddrinfo.c > index 9df045f6..64ad259a 100644 > --- a/src/network/getaddrinfo.c > +++ b/src/network/getaddrinfo.c > @@ -16,6 +16,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru > char canon[256], *outcanon; > int nservs, naddrs, nais, canon_len, i, j, k; > int family = AF_UNSPEC, flags = 0, proto = 0, socktype = 0; > + int no_family = 0; > struct aibuf *out; > > if (!host && !serv) return EAI_NONAME; > @@ -82,7 +83,7 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru > default: > return EAI_SYSTEM; > } > - if (family == tf[i]) return EAI_NONAME; > + if (family == tf[i]) no_family = 1; > family = tf[1-i]; > } > } > @@ -93,6 +94,8 @@ int getaddrinfo(const char *restrict host, const char *restrict serv, const stru > naddrs = __lookup_name(addrs, canon, host, family, flags); > if (naddrs < 0) return naddrs; > > + if (no_family) return EAI_NODATA; > + > nais = nservs * naddrs; > canon_len = strlen(canon); > out = calloc(1, nais * sizeof(*out) + canon_len + 1); > diff --git a/src/network/gethostbyname2_r.c b/src/network/gethostbyname2_r.c > index c9f3acc4..a5eb67fe 100644 > --- a/src/network/gethostbyname2_r.c > +++ b/src/network/gethostbyname2_r.c > @@ -23,6 +23,9 @@ int gethostbyname2_r(const char *name, int af, > case EAI_NONAME: > *err = HOST_NOT_FOUND; > return 0; > + case EAI_NODATA: > + *err = NO_DATA; > + return 0; > case EAI_AGAIN: > *err = TRY_AGAIN; > return EAGAIN; > diff --git a/src/network/lookup_name.c b/src/network/lookup_name.c > index bec6ba22..37d481f9 100644 > --- a/src/network/lookup_name.c > +++ b/src/network/lookup_name.c > @@ -79,7 +79,7 @@ static int name_from_hosts(struct address buf[static MAXADDRS], char canon[stati > case 0: > continue; > default: > - badfam = EAI_NONAME; > + badfam = EAI_NODATA; > break; > } > > @@ -175,7 +175,7 @@ static int name_from_dns(struct address buf[static MAXADDRS], char canon[static > __dns_parse(abuf[i], alens[i], dns_parse_callback, &ctx); > > if (ctx.cnt) return ctx.cnt; > - return EAI_NONAME; > + return EAI_NODATA; > } > > static int name_from_dns_search(struct address buf[static MAXADDRS], char canon[static 256], const char *name, int family) One more thing: presently IP literals with address family mismatching the request error with EAI_NONAME. glibc has an error EAI_ADDRFAMILY for this, but semantically it's equivalent to the above proposed EAI_NODATA: "Name has no usable address" and I think we should just use EAI_NODATA here. In principle EAI_ADDRFAMILY would be nice if it could tell the caller (definitively) "this name *does* have an address of some sort, but not in the requested address family or as limited by AI_ADDRCONFIG". But doing this requires always looking up both v4 and v6 even when the caller did not ask for them. That is, it introduces a distinction that requires more work just to give a more specific error. IMO this is not a good thing unless the specificity would actually have some use, which it doesn't seem to here. And indeed glibc doesn't do that either. It only uses EAI_ADDRFAMILY for IP literals. So, in addition to the above patch, for now I propose just changing __lookup_ipliteral to return EAI_NODATA for mismatching family instead of EAI_NONANE. We could add EAI_ADDRFAMILY with behavior matching glibc later if we really want to. Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.