Gethostbyname() requires reverse lookup to work?

We ran into a problem last night where we could ping a host, telnet to
it, ssh to it, look it up with dig, and traceroute to it, but the
following ruby code failed:

ruby -rsocket -e ‘p Socket.gethostbyname(“host”)’

The problem turned out to be that Ruby was looking up the host, and then
doing a reverse lookup (and it also turned out that reverse lookup for
this host was broken). We fixed the name server, and all was well.

But I’m curious: what is the reason for writing socket.c this way? It
seems almost silly to me to use getaddrinfo() to look up a host and then
to use gethostbyaddr() to get the corresponding hostent structure (which
to the best that I can tell, is what Ruby is doing; please correct me if
I am mistaken). Why doesn’t Ruby call gethostbyname() or
getipnodebyname() directly?

Paul

I am mistaken). Why doesn't Ruby call gethostbyname() or

pigeon% less socket.c
[...]

/*
* NOTE: using gethostbyname() against AF_INET6 is a bad idea, as it
* does not initialize sin_flowinfo nor sin_scope_id properly.
*/

[...]
pigeon%

Guy Decoux

ts wrote:

I am mistaken). Why doesn’t Ruby call gethostbyname() or

pigeon% less socket.c
[…]

/*

  • NOTE: using gethostbyname() against AF_INET6 is a bad idea, as it
  • does not initialize sin_flowinfo nor sin_scope_id properly.
    */

[…]
pigeon%

Is this the reason why Ruby needs an /etc/hosts with

data to be able to connect? Can’t this be solved somehow?

···


Giuseppe “Oblomov” Bilotta

Axiom I of the Giuseppe Bilotta
theory of IT:
Anything is better than MS

ts wrote:

I am mistaken). Why doesn’t Ruby call gethostbyname() or

pigeon% less socket.c
[…]

/*

  • NOTE: using gethostbyname() against AF_INET6 is a bad idea, as it
  • does not initialize sin_flowinfo nor sin_scope_id properly.
    */

[…]
pigeon%

Guy Decoux

Couldn’t you simply check RES_USE_INT6 and call gethostbyname or
gethostbyname2 as appropriate? I’m looking at Stevens, “Unix Network
Programming”, p.240-249

Regards,

Dan

Couldn't you simply check RES_USE_INT6 and call gethostbyname or
gethostbyname2 as appropriate? I'm looking at Stevens, "Unix Network
Programming", p.240-249

RFC 2553

6.1 Nodename-to-Address Translation

   The commonly used function gethostbyname() is inadequate for many
   applications, first because it provides no way for the caller to
   specify anything about the types of addresses desired (IPv4 only,
   IPv6 only, IPv4-mapped IPv6 are OK, etc.), and second because many
   implementations of this function are not thread safe. RFC 2133
   defined a function named gethostbyname2() but this function was also
   inadequate, first because its use required setting a global option
   (RES_USE_INET6) when IPv6 addresses were required, and second because
   a flag argument is needed to provide the caller with additional
   control over the types of addresses required.

Guy Decoux

ts wrote:

Couldn’t you simply check RES_USE_INT6 and call gethostbyname or
gethostbyname2 as appropriate? I’m looking at Stevens, “Unix Network
Programming”, p.240-249

RFC 2553

6.1 Nodename-to-Address Translation

The commonly used function gethostbyname() is inadequate for many
applications, first because it provides no way for the caller to
specify anything about the types of addresses desired (IPv4 only,
IPv6 only, IPv4-mapped IPv6 are OK, etc.), and second because many
implementations of this function are not thread safe. RFC 2133
defined a function named gethostbyname2() but this function was also
inadequate, first because its use required setting a global option
(RES_USE_INET6) when IPv6 addresses were required, and second because
a flag argument is needed to provide the caller with additional
control over the types of addresses required.

Guy Decoux

Ok, but the question I have to ask is whether or not this actually affects
anyone. Looking through the Perl 5.8 source code, I don’t even see any
refernce to gethostbyname2, although they use the reentrant functions where
available.

Using Google, I searched through the comp.lang.perl.misc archives. With
over 10 years of posts, I found exactly 31 posts regarding IPv6, and NONE
of them (that I saw) have any complaints with regards to incompatibility
and/or thread problems with IPv6 (although, I realize Perl didn’t really
support threads until recently). I also couldn’t find a single reference
to RFC 2553.

My point is, I think the code should be written so as not to worry about
those (very?) rare cases where it might fail with regards to IPv6. I think
reverse lookups are likely to be a much more prevalent cause of failures.

Just my .02

Regards,

Dan

The ideal solution, I think, is to use a resolver library that uses
rb_f_select() instead of select(); then we don’t have any issues to
worry about with thread-safety and global variables and such.

Barring that solution, I suppose getaddrinfo() seems reasonable, but
using gethostbyaddr() to get a hostent* out of the addrinfo structure
does not. Perhaps writing a function that can create the hostent*
directly from the addrinfo structure might work?

I don’t know much about sockets or IPV6; what do most people do who have
to deal with IPv6 do to resolve addresses?

Paul

···

On Sun, Sep 01, 2002 at 04:57:33AM +0900, Daniel Berger wrote:

My point is, I think the code should be written so as not to worry about
those (very?) rare cases where it might fail with regards to IPv6. I think
reverse lookups are likely to be a much more prevalent cause of failures.