gethostbyname_r returns NULL when hostname has dash

We have a code to find the DNS entry of a host that has a trailing '-' in its url (format example: mysite-.watch.com):

if(gethostbyname_r(host,host_ent,host_buffer,host_buffer_size,&host_error)==NULL) 
{
//failed
}

But when remove the '-' from the host name the code does not return failure. IE and nslookup works fine.

What we need to do in such a case?

Below are my personal findings:

Example 1:

> host nyustern-.collegemailer.com
nyustern-.collegemailer.com has address 209.200.118.155

> host nyustern.collegemailer.com
nyustern.collegemailer.com has address 209.200.118.155

Example 2:

> nslookup nyustern-.collegemailer.com
Note:  nslookup is deprecated and may be removed from future releases.
Consider using the `dig' or `host' programs instead.  Run nslookup with
the `-sil[ent]' option to prevent this message from appearing.
Server:         xx.xxx.xx.xxx
Address:       xx.xxx.xx.xxx#xx
 
Non-authoritative answer:
Name:   nyustern-.collegemailer.com
Address: 209.200.118.155
 
> nslookup nyustern.collegemailer.com
Note:  nslookup is deprecated and may be removed from future releases.
Consider using the `dig' or `host' programs instead.  Run nslookup with
the `-sil[ent]' option to prevent this message from appearing.
Server:         xx.xxx.xx.xxx
Address:       xx.xxx.xx.xxx#xx
 
Non-authoritative answer:
Name:   nyustern.collegemailer.com
Address: 209.200.118.155
 

Example 3:

This code uses gethostbyname_r method to determine the address:-

> a.out nyuster-n.collegemailer.com
addresses:   209.200.118.155
> a.out ny-uster-n.collegemailer.com
addresses:   209.200.118.155
> a.out ny-uster-n-.collegemailer.com
unknown host `ny-uster-n-.collegemailer.com'
> a.out ny---uster-n.collegemailer.com
addresses:   209.200.118.155
> a.out nyustern.collegemailer.com
addresses:   209.200.118.155
>

I am unsure whether '-' in hostname ignored or does not has a functionality. In such a case having a trailing '-' is just a corner off case.

Looks like that particular domain is running some funky resolver which resolves almost anything. I'd guess their resolver is configured to resolve everything, but has a bug.

vnix$ host fnordityfnord.collegemailer.com
fnordityfnord.collegemailer.com has address 209.200.118.155
vnix$ host thisabsurdhostnamecouldnotpossiblyexist.collegemailer.com
thisabsurdhostnamecouldnotpossiblyexist.collegemailer.com has address 209.200.118.155
vnix$ host '!*?'.collegemailer.com
!*?.collegemailer.com has address 209.200.118.155

Punycode - Wikipedia, the free encyclopedia has some special cases relating to hyphens in host names.

I am quiet unsure now of what extra we need to code here. Is there any library we need to include? How can we resolve this issue?

What does h_errno say when you get the failure? The man page seems to suggest to use getnameinfo() instead, have you tried that? My version of gethostbyname_r returns an int, do you have a different implementation?

I did a sample code:

Code:

#include <netdb.h>
#include <stdio.h>
#include <alloca.h>

int
main (void)
{
  struct hostent hostbuf, *hp;
  size_t hstbuflen;
  char *tmphstbuf;
  int res;
  int herr;

  hstbuflen = 1024;
  tmphstbuf = (char *)alloca (hstbuflen);

res = gethostbyname_r ("nyustern-.collegemailer.com", &hostbuf, tmphstbuf, hstbuflen, &hp, &herr);
        herror("Error");
        printf("Hsterror [%s]\n" , hstrerror (h_errno ));

  printf ("gethostbyname_r returned: %d\n", res);
  printf ("herr: %d\n", herr);
  printf ("hp is %s\n", hp == NULL ? "null" : "set");
}

Output:

cc test_host.cpp && a.out

Error: Unknown host
Hsterror [Unknown host]
gethostbyname_r returned: 0
herr: 3
hp is null

The getnameinfo() function takes a socket address as input and returns the corresponding node name and service location.
Can you be more specific regards to my requirement?

This appears to be illegal according to rfc 952.
RFC 952 (rfc952) - DoD Internet host table specification

<name>  ::= <let>[*[<let-or-digit-or-hyphen>]<let-or-digit>]

Not sure but I am able to open through IE

Actually Windows' resolver is known to simply drop illegal characters off the end of a host name if it helps to resolve it.

This is wired output but as Era stated I could believe it:

From Unix box:

11> telnet nyustern-.collegemailer.com 80
telnet: nyustern-.collegemailer.com: Name or service not known
nyustern-.collegemailer.com: Unknown host

12> telnet nyustern.collegemailer.com 80
Trying 209.200.118.155...
Connected to nyustern.collegemailer.com.

From DOS command window:

C:\>telnet nyustern-.collegemailer.com 80


GET / HTTP/1.0
Host: nyustern-.collegemailer.com

HTTP/1.1 302 Object moved
Connection: close

But my issue is how can I resolve this at code level - what I need to do in such a case?

You can probably approximate what Microsoft is doing by simply dropping any illegal trailing characters.

By the by, the highlighted Server: header is a red herring; the issue is with how a Windows client would resolve the domain name.

If you can run tcpdump on the DNS traffic from the Windows box while it resolves and visits the site in IE (or simply opens a telnet session), you should see what host name the Windows box is actually resolving.

I tried ways to dump tcp packets in windows and Unix but unfortunately unable to succeed cause I have a windows network login and ssh to unix development servers as developer.

Is there any other way I can do away with findings?

You don't have any way to get access to a local Windows box? Lucky bastard. (-:

I believe there are VMware Player images with preinstalled Windows images you could play around with. Install Ethereal and watch it resolve. DNS is UDP port 53.