[Xorg] Re: 64-bit applications and hostnames that start with a digit

Jim Gettys Jim.Gettys at hp.com
Thu Mar 25 06:11:56 PST 2004


An extract from RFC 2396 "Uniform Resource Identifiers (URI): Generic
Syntax"'s ABNF is:

  The host is a domain name of a network host, or its IPv4 address as a
   set of four decimal digit groups separated by ".".  Literal IPv6
   addresses are not supported.
      hostport      = host [ ":" port ]
      host          = hostname | IPv4address
      hostname      = *( domainlabel "." ) toplabel [ "." ]
      domainlabel   = alphanum | alphanum *( alphanum | "-" ) alphanum
      toplabel      = alpha | alpha *( alphanum | "-" ) alphanum
      IPv4address   = 1*digit "." 1*digit "." 1*digit "." 1*digit
      port          = *digit

My ABNF is getting a bit rusty, and I've never been great at
grokking ABNF notation: folks, please check me here.

Hosts can be either hostname's or IPv4 address strings.
I think the toplabel requires that the first character be alpha, and
not a number.

                                           - Jim

On Wed, 2004-03-24 at 20:45, Paul Anderson wrote:
> I stumbled across a 64-bit issue in the transport layer that occurs
> when connecting to hostnames that start with a digit (rather than a
> letter).  This type of hostname appears to be allowed by RFC1123.
> 
> The problem occurs in xc/lib/xtrans/Xtranssock.c in
> the function TRANS(SocketINETConnect)().  The variable tmpaddr
> is defined as an "unsigned long".  Later in the routine, there
> is a block that looks something like:
> 
>     /*
>      * fill in sin_addr
>      */
> 
>     /* check for ww.xx.yy.zz host string */
> 
>     if (isascii (host[0]) && isdigit (host[0])) {
> 	tmpaddr = inet_addr (host); /* returns network byte order */
>     } else {
> 	tmpaddr = -1;
>     }
> 
>     PRMSG (4,"TRANS(SocketINETConnect) inet_addr(%s) = %p\n",
> 	host, tmpaddr, 0);
> 
>     if ((long)tmpaddr == -1L)
>     {
>         ....call XGethostbyname(host,...) and then fill in sockname.sin_addr
>         accordingly
>     }
>     else
>     {
>         sockname.sin_addr.s_addr = tmpaddr;
>     }
> 
> 
> The problem is that if the hostname starts with a digit, we'll
> call inet_addr(), and this will fail with a value of -1 (because
> the string isn't in the internet standard "dot" notation). 
> 
> In a 64-bit library, the "if" test that compares tmpaddr to -1L
> will fail because tmpaddr is only 0xffffffff whereas -1L is
> 0xffffffffffffffff.  As a result, we'll end up taking the "else"
> clause and copying -1 to sockname.sin_addr.s_addr, causing the 
> subsequent call to connect() to fail.
> 
> To fix this, I'd like to use something more portable and get 
> away from having to cast values, since those can cause problems,
> such as in this situation.  Does anyone have any objections 
> to something such as the following:
> 
>     in_addr_t         tmpaddr;
> 
>     ....
> 
>     /* check for ww.xx.yy.zz host string */
> 
>     if (isascii (host[0]) && isdigit (host[0])) {
> 	tmpaddr = inet_addr (host); /* returns network byte order */
>     } else {
> 	tmpaddr = INADDR_NONE;
>     }
> 
>     PRMSG (4,"TRANS(SocketINETConnect) inet_addr(%s) = %p\n",
> 	host, tmpaddr, 0);
> 
>     if (tmpaddr == INADDR_NONE)
>     {
>         ....call XGethostbyname(host,...) and then fill in sockname.sin_addr
>         accordingly
>     }
>     else ...
> 
> 
> >From the header files I've seen, INADDR_NONE is defined properly
> to cast the -1 to (in_addr_t), so this seems like a safer way
> to accomplish what the original code does.
> 
> Any comments?  Does anyone have any better ideas?
> 
> -paul
> 
> _______________________________________________
> xlibs mailing list
> xlibs at freedesktop.org
> http://freedesktop.org/mailman/listinfo/xlibs
-- 
Jim Gettys <Jim.Gettys at hp.com>
HP Labs, Cambridge Research Laboratory





More information about the xorg mailing list