[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