This is the mail archive of the mailing list for the glibc project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC PATCH] getaddrinfo: Force name resolution for AI_CANONNAME [BZ# 24182]

When getaddrinfo() is called with a numeric nodename argument (e.g.
67882190), we should try name resolution if AI_CANONNAME is set. RFC
1123 allows digits-only hostnames, but inet_aton_exact() can interpret
these as valid IPv4 addresses in a 32-bit number form. This behaviour
causes the internal gaih_inet() call to think a numeric hostname is a
valid IPv4 address and skip name resolution.

One can reproduce this by following these steps:
1) Append numeric hostname records to /etc/hosts:
$ head -n2 /etc/hosts localhost 1234

2) Change local hostname to the numeric record:
$ sudo hostname 1234

3) Call `hostname -f` (output should be ''):
$ hostname -f

This patch forces name resolution if the AI_CANONNAME flag is set. Even
if inet_aton_exact() identifies the input name as being a valid IPv4
address, we will try name resolution in case it's a valid hostname. If
no hostname is found after resolution, the input name is still copied
to the ai_canonname field.

The patch was tested on amd64, and the glibc test suite showed no
regressions. Further use case tests showed that current behaviour is
not modified w.r.t. IPv4 addresses.


This is a tentative patch suggestion for BZ# 24182. The general idea is
already being discussed there, but I would like some more thoughts on
the patch specifically, if possible. Likely there are many ways to
tackle this and I'm unsure which would be best suited. Thanks!

 sysdeps/posix/getaddrinfo.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/sysdeps/posix/getaddrinfo.c b/sysdeps/posix/getaddrinfo.c
index aa054b620f2a..fa9e2d6ad3b1 100644
--- a/sysdeps/posix/getaddrinfo.c
+++ b/sysdeps/posix/getaddrinfo.c
@@ -505,9 +505,6 @@ gaih_inet (const char *name, const struct gaih_service *service,
 	      result = -EAI_ADDRFAMILY;
 	      goto free_and_return;
-	  if (req->ai_flags & AI_CANONNAME)
-	    canon = name;
       else if (at->family == AF_UNSPEC)
@@ -548,7 +545,8 @@ gaih_inet (const char *name, const struct gaih_service *service,
-      if (at->family == AF_UNSPEC && (req->ai_flags & AI_NUMERICHOST) == 0)
+      if ((at->family == AF_UNSPEC || (req->ai_flags & AI_CANONNAME))
+          && (req->ai_flags & AI_NUMERICHOST) == 0)
 	  struct gaih_addrtuple **pat = &at;
 	  int no_data = 0;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]