There is a standard (required) hostname scheme, whois.nic.tld, for the
new gTLDs. For months whois-servers.net didn't list any of the new ones,
they are starting to catch up but are still behind,

$ unbound-host sucks.whois-servers.net
Host sucks.whois-servers.net not found: 3(NXDOMAIN).

$ unbound-host whois.nic.sucks
whois.nic.sucks is an alias for whois.sucks.aridnrs.net.au.
whois.sucks.aridnrs.net.au has address 120.29.248.191
whois.sucks.aridnrs.net.au has IPv6 address 2001:dcd:11::f0bf

and the extra indirection just adds fragility in the cases where they do
have the right details, so the diff teaches whois to use them directly.

Any comments/OKs?

Index: whois.c
===================================================================
RCS file: /cvs/src/usr.bin/whois/whois.c,v
retrieving revision 1.46
diff -u -p -r1.46 whois.c
--- whois.c     3 Jan 2014 15:25:18 -0000       1.46
+++ whois.c     9 Apr 2015 08:56:54 -0000
@@ -278,6 +278,12 @@ choose_server(const char *name, const ch
        char *nserver;
        char *ep;
        size_t len;
+       struct addrinfo hints, *res;
+
+       memset(&hints, 0, sizeof(hints));
+       hints.ai_flags = 0;
+       hints.ai_family = AF_UNSPEC;
+       hints.ai_socktype = SOCK_STREAM;
 
        if (country != NULL)
                qhead = country;
@@ -299,8 +305,33 @@ choose_server(const char *name, const ch
        if ((nserver = realloc(server, len)) == NULL)
                err(1, "realloc");
        server = nserver;
-       strlcpy(server, qhead, len);
-       strlcat(server, QNICHOST_TAIL, len);
+
+       /*
+        * Post-2003 ("new") gTLDs are all supposed to have "whois.nic.domain"
+        * (per registry agreement), some older gTLDs also support this...
+        */
+       strlcpy(server, "whois.nic.", len);
+       strlcat(server, qhead, len);
+
+       /* most ccTLDs don't do this, but QNICHOST/whois-servers mostly works */
+       if ((strlen(qhead) == 2 ||
+           /* and is required for most of the <=2003 TLDs/gTLDs */
+           strncasecmp(qhead, "org", 3) == 0 ||
+           strncasecmp(qhead, "com", 3) == 0 ||
+           strncasecmp(qhead, "net", 3) == 0 ||
+           strncasecmp(qhead, "cat", 3) == 0 ||
+           strncasecmp(qhead, "pro", 3) == 0 ||
+           strncasecmp(qhead, "info", 4) == 0 ||
+           strncasecmp(qhead, "aero", 4) == 0 ||
+           strncasecmp(qhead, "jobs", 4) == 0 ||
+           strncasecmp(qhead, "mobi", 4) == 0 ||
+           strncasecmp(qhead, "museum.", 6) == 0 ||
+            /* for others, if whois.nic.TLD doesn't exist, try whois-servers */
+           getaddrinfo(server, NULL, &hints, &res) != 0)) {
+               strlcpy(server, qhead, len);
+               strlcat(server, QNICHOST_TAIL, len);
+       }
+
        return (server);
 }
Index: whois.1
===================================================================
RCS file: /cvs/src/usr.bin/whois/whois.1,v
retrieving revision 1.32
diff -u -p -r1.32 whois.1
--- whois.1     5 Mar 2013 16:09:10 -0000       1.32
+++ whois.1     9 Apr 2015 09:25:10 -0000
@@ -97,8 +97,11 @@ By default
 .Nm
 constructs the name of a whois server to use from the top-level domain
 .Pq Tn TLD
-of the supplied (single) argument, and appending
-.Qq Li .whois-servers.net .
+of the supplied (single) argument.
+For newer generic domains (gTLDs), a lookup for whois.nic.tld is attempted.
+For other TLDs, or if this lookup fails,
+.Qq Li .whois-servers.net
+is appended to the TLD.
 This effectively allows a suitable whois server to be selected
 automatically for a large number of
 .Tn TLDs .
 

Reply via email to