Message ID | 20170905160530.19525-4-stlman@poczta.fm |
---|---|
State | New |
Headers | show |
Series | Make getaddrinfo(3) return zone id from /etc/hosts for link-local IPv6 addresses | expand |
On 09/05/2017 06:05 PM, Łukasz Stelmach wrote: > Add af (address family) to the list of arguments of gethostbyname4_r > function in files, dns, nis and nisplus module and rename the function to > gethostbyname5_r. Pass the af value to the underlying parsing functions. > Define gethostbyname4_r as a wrapper for the former passing af set > to AF_UNSPEC. I'd prefer if we have a single ultimate name resolution function, instead of doing function 5 now, and function 6 later, when we have dealt with the malloc matters. One way to deal with the dlmopen/static dlopen issue would be to define a deallocation function which goes with the 5 function. If this function called free, it would automatically end up at the right definition. Thanks, Florian
Dnia 12 września 2017 12:03:00 CEST, Florian Weimer <fweimer@redhat.com> napisał(a): >On 09/05/2017 06:05 PM, Łukasz Stelmach wrote: >> Add af (address family) to the list of arguments of gethostbyname4_r >> function in files, dns, nis and nisplus module and rename the >function to >> gethostbyname5_r. Pass the af value to the underlying parsing >functions. >> Define gethostbyname4_r as a wrapper for the former passing af set >> to AF_UNSPEC. > >I'd prefer if we have a single ultimate name resolution function, >instead of doing function 5 now, and function 6 later, when we have >dealt with the malloc matters. This sounds like a major debate. Do you know who's in charge in this parts of glibc? >One way to deal with the dlmopen/static dlopen issue would be to define >a deallocation function which goes with the 5 function. If this >function called free, it would automatically end up at the right >definition. This means almost nothing to me (-; which means, probably I am not the right guy to do it.
On 09/12/2017 12:44 PM, Łukasz Stelmach wrote: > Dnia 12 września 2017 12:03:00 CEST, Florian Weimer <fweimer@redhat.com> napisał(a): >> On 09/05/2017 06:05 PM, Łukasz Stelmach wrote: >>> Add af (address family) to the list of arguments of gethostbyname4_r >>> function in files, dns, nis and nisplus module and rename the >> function to >>> gethostbyname5_r. Pass the af value to the underlying parsing >> functions. >>> Define gethostbyname4_r as a wrapper for the former passing af set >>> to AF_UNSPEC. >> >> I'd prefer if we have a single ultimate name resolution function, >> instead of doing function 5 now, and function 6 later, when we have >> dealt with the malloc matters. > > This sounds like a major debate. Do you know who's in charge in this parts of glibc? It's a community project. We don't have strong component ownership. I have taken care of networking-related matters for some time now. >> One way to deal with the dlmopen/static dlopen issue would be to define >> a deallocation function which goes with the 5 function. If this >> function called free, it would automatically end up at the right >> definition. > > This means almost nothing to me (-; which means, probably I am not the right guy to do it. We currently pass a fixed-size buffer into the NSS service module. The NSS service module can fail with NSS_STATUS_TRYAGAIN/NETDB_INTERNAL/ERANGE to indicate that the buffer is too small. The caller is supposed to try again with a larger buffer. This is very inefficient. It can result in a large number of DNS queries if there are many addresses (A/AAAA over UDP, then over TCP). We could avoid this if the NSS service module allocates space for the result because it knows the required size. But the module could use a different malloc than the main program (like Windows DLLs, but for GNU, this is a special case which does not apply to regular DSO usage). There are two ways to fix this: The NSS module could provide a deallocation function, or we could add a mechanism to the dynamic linker that ensures the mallocs always match. The second approach is quite hard to implement. The first approach has other benefits (e.g., the service module could return a pointer into a cache and use reference counting instead of direct malloc/free to manage the memory). I don't see your name in the maintainers list on the wiki. Since your current patches already are substantial contribution, we need to discuss the matter of copyright assignment: https://sourceware.org/glibc/wiki/Contribution%20checklist#FSF_copyright_Assignment I suggest you contact the FSF to eliminate that roadblock before working on these patches further. Thanks, Florian
Dnia 12 września 2017 13:00:41 CEST, Florian Weimer <fweimer@redhat.com> napisał(a): >I don't see your name in the maintainers list on the wiki. Since your >current patches already are substantial contribution, we need to >discuss >the matter of copyright assignment: > >https://sourceware.org/glibc/wiki/Contribution%20checklist#FSF_copyright_Assignment > >I suggest you contact the FSF to eliminate that roadblock before >working >on these patches further. I suppose, I should send https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/Copyright/request-assign.future. Am I right?
On 09/12/2017 02:46 PM, Łukasz Stelmach wrote: > Dnia 12 września 2017 13:00:41 CEST, Florian Weimer <fweimer@redhat.com> napisał(a): > >> I don't see your name in the maintainers list on the wiki. Since your >> current patches already are substantial contribution, we need to >> discuss >> the matter of copyright assignment: >> >> https://sourceware.org/glibc/wiki/Contribution%20checklist#FSF_copyright_Assignment >> >> I suggest you contact the FSF to eliminate that roadblock before >> working >> on these patches further. > > I suppose, I should send https://git.savannah.gnu.org/cgit/gnulib.git/plain/doc/Copyright/request-assign.future. Am I right? Yes, it's a valid option if you want to go that route. Thanks, Florian
diff --git a/nis/Versions b/nis/Versions index ef9a512417..537f0aa3c0 100644 --- a/nis/Versions +++ b/nis/Versions @@ -96,6 +96,7 @@ libnss_nis { _nss_nis_setnetgrent; _nss_nis_setprotoent; _nss_nis_setpwent; _nss_nis_setrpcent; _nss_nis_setservent; _nss_nis_setspent; _nss_nis_initgroups_dyn; _nss_nis_gethostbyname4_r; + _nss_nis_gethostbyname5_r; } } @@ -126,6 +127,6 @@ libnss_nisplus { _nss_nisplus_setnetent; _nss_nisplus_setnetgrent; _nss_nisplus_setprotoent; _nss_nisplus_setpwent; _nss_nisplus_setrpcent; _nss_nisplus_setservent; _nss_nisplus_setspent; _nss_nisplus_initgroups_dyn; - _nss_nisplus_gethostbyname4_r; + _nss_nisplus_gethostbyname4_r; _nss_nisplus_gethostbyname5_r; } } diff --git a/nis/nss_nis/nis-hosts.c b/nis/nss_nis/nis-hosts.c index f64dbdaecb..3a156aa7ee 100644 --- a/nis/nss_nis/nis-hosts.c +++ b/nis/nss_nis/nis-hosts.c @@ -454,7 +454,7 @@ _nss_nis_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af, enum nss_status -_nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, +_nss_nis_gethostbyname5_r (const char *name, int af, struct gaih_addrtuple **pat, char *buffer, size_t buflen, int *errnop, int *herrnop, int32_t *ttlp) { @@ -530,7 +530,7 @@ _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, buflen -= pad; struct hostent host; - int parse_res = parse_line (result, &host, data, buflen, errnop, AF_UNSPEC, + int parse_res = parse_line (result, &host, data, buflen, errnop, af, 0); if (__glibc_unlikely (parse_res < 1)) { @@ -565,3 +565,12 @@ _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, return NSS_STATUS_SUCCESS; } + +enum nss_status +_nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + char *buffer, size_t buflen, int *errnop, + int *herrnop, int32_t *ttlp) +{ + return _nss_nis_gethostbyname5_r (name, AF_UNSPEC, pat, buffer, buflen, + errnop, herrnop, ttlp); +} diff --git a/nis/nss_nisplus/nisplus-hosts.c b/nis/nss_nisplus/nisplus-hosts.c index 31dfd31fbd..d9c5d7a974 100644 --- a/nis/nss_nisplus/nisplus-hosts.c +++ b/nis/nss_nisplus/nisplus-hosts.c @@ -579,13 +579,13 @@ _nss_nisplus_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af, enum nss_status -_nss_nisplus_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, +_nss_nisplus_gethostbyname5_r (const char *name, int af, struct gaih_addrtuple **pat, char *buffer, size_t buflen, int *errnop, int *herrnop, int32_t *ttlp) { struct hostent host; - enum nss_status status = internal_gethostbyname2_r (name, AF_UNSPEC, &host, + enum nss_status status = internal_gethostbyname2_r (name, af, &host, buffer, buflen, errnop, herrnop, 0); if (__glibc_likely (status == NSS_STATUS_SUCCESS)) @@ -617,3 +617,12 @@ _nss_nisplus_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, return status; } + +enum nss_status +_nss_nisplus_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + char *buffer, size_t buflen, int *errnop, + int *herrnop, int32_t *ttlp) +{ + return _nss_nisplus_gethostbyname5_r (name, AF_UNSPEC, pat, buffer, + buflen, errnop, herrnop, ttlp); +} diff --git a/nss/Versions b/nss/Versions index 50268ed9b5..72adf4c806 100644 --- a/nss/Versions +++ b/nss/Versions @@ -44,6 +44,7 @@ libnss_files { _nss_files_gethostbyname2_r; _nss_files_gethostbyname3_r; _nss_files_gethostbyname4_r; + _nss_files_gethostbyname5_r; _nss_files_gethostbyname_r; _nss_files_gethostent_r; diff --git a/nss/nss_files/files-hosts.c b/nss/nss_files/files-hosts.c index 28eb73fb2d..c6067cc641 100644 --- a/nss/nss_files/files-hosts.c +++ b/nss/nss_files/files-hosts.c @@ -404,7 +404,7 @@ _nss_files_gethostbyname2_r (const char *name, int af, struct hostent *result, } enum nss_status -_nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, +_nss_files_gethostbyname5_r (const char *name, int af, struct gaih_addrtuple **pat, char *buffer, size_t buflen, int *errnop, int *herrnop, int32_t *ttlp) { @@ -428,7 +428,7 @@ _nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, struct hostent result; status = internal_getent (stream, &result, buffer, buflen, errnop, - herrnop, AF_UNSPEC, 0, &in6_zone_id); + herrnop, af, 0, &in6_zone_id); if (status != NSS_STATUS_SUCCESS) break; @@ -518,3 +518,12 @@ _nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, return status; } + +enum nss_status +_nss_files_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + char *buffer, size_t buflen, int *errnop, + int *herrnop, int32_t *ttlp) +{ + return _nss_files_gethostbyname5_r (name, AF_UNSPEC, pat, buffer, buflen, + errnop, herrnop, ttlp); +} diff --git a/resolv/Versions b/resolv/Versions index b05778d965..2ae1048908 100644 --- a/resolv/Versions +++ b/resolv/Versions @@ -96,7 +96,7 @@ libnss_dns { _nss_dns_gethostbyname_r; _nss_dns_getnetbyaddr_r; _nss_dns_getnetbyname_r; _nss_dns_getcanonname_r; _nss_dns_gethostbyaddr2_r; - _nss_dns_gethostbyname4_r; + _nss_dns_gethostbyname4_r; _nss_dns_gethostbyname5_r; } } diff --git a/resolv/nss_dns/dns-host.c b/resolv/nss_dns/dns-host.c index 7cd54ab504..dddb8f4bef 100644 --- a/resolv/nss_dns/dns-host.c +++ b/resolv/nss_dns/dns-host.c @@ -308,7 +308,7 @@ _nss_dns_gethostbyname_r (const char *name, struct hostent *result, enum nss_status -_nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, +_nss_dns_gethostbyname5_r (const char *name, int af, struct gaih_addrtuple **pat, char *buffer, size_t buflen, int *errnop, int *herrnop, int32_t *ttlp) { @@ -344,10 +344,28 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, int nans2p = 0; int resplen2 = 0; int ans2p_malloced = 0; + int type; int olderr = errno; enum nss_status status; - int n = __res_context_search (ctx, name, C_IN, T_QUERY_A_AND_AAAA, + + switch (af) { + case AF_UNSPEC: + type = T_QUERY_A_AND_AAAA; + break; + case AF_INET: + type = T_A; + break; + case AF_INET6: + type = T_AAAA; + break; + default: + *herrnop = NO_DATA; + *errnop = EAFNOSUPPORT; + return NSS_STATUS_UNAVAIL; + } + + int n = __res_context_search (ctx, name, C_IN, type, host_buffer.buf->buf, 2048, &host_buffer.ptr, &ans2p, &nans2p, &resplen2, &ans2p_malloced); if (n >= 0) @@ -397,6 +415,16 @@ _nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, } +enum nss_status +_nss_dns_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, + char *buffer, size_t buflen, int *errnop, + int *herrnop, int32_t *ttlp) +{ + return _nss_dns_gethostbyname5_r (name, AF_UNSPEC, pat, buffer, buflen, + errnop, herrnop,ttlp); +} + + extern enum nss_status _nss_dns_gethostbyaddr2_r (const void *addr, socklen_t len, int af, struct hostent *result,
Add af (address family) to the list of arguments of gethostbyname4_r function in files, dns, nis and nisplus module and rename the function to gethostbyname5_r. Pass the af value to the underlying parsing functions. Define gethostbyname4_r as a wrapper for the former passing af set to AF_UNSPEC. Signed-off-by: Łukasz Stelmach <stlman@poczta.fm> --- nis/Versions | 3 ++- nis/nss_nis/nis-hosts.c | 13 +++++++++++-- nis/nss_nisplus/nisplus-hosts.c | 13 +++++++++++-- nss/Versions | 1 + nss/nss_files/files-hosts.c | 13 +++++++++++-- resolv/Versions | 2 +- resolv/nss_dns/dns-host.c | 32 ++++++++++++++++++++++++++++++-- 7 files changed, 67 insertions(+), 10 deletions(-)