[#7708] Bug in libsnmp-ruby1.8 — Hadmut Danisch <hadmut@...>

Hi,

8 messages 2006/04/11
[#7709] Re: Bug in libsnmp-ruby1.8 — Eric Hodel <drbrain@...7.net> 2006/04/11

On Apr 11, 2006, at 6:23 AM, Hadmut Danisch wrote:

[#7770] Re: possible defect in array.c — "Brown, Warren" <warrenbrown@...>

> rb_range_beg_len (in range.c) does set beg and len.

13 messages 2006/04/26
[#7771] Re: possible defect in array.c — "Pat Eyler" <rubypate@...> 2006/04/26

On 4/26/06, Brown, Warren <warrenbrown@aquire.com> wrote:

Socket.gethostbyname returns sockaddrs of wrong address family

From: Sam Roberts <sroberts@...>
Date: 2006-04-09 04:46:35 UTC
List: ruby-core #7691
Socket.gethostbyname doesn't behave like gethostbyname(3).

It can return multiple sockaddrs, this is expected, but they are NOT all
necessarily in the indicated address family:

On my system, OS x 10.3 with IPv6 enabled, I see:

Socket.gethostbyname "localhost"
=> ["localhost", [], 30, "\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001", "\177\000\000\001"]
                    ^^^^

30 == Socket::AF_INET6, but the second sockaddr is NOT an IPv6 sockaddr.

If you are familiar with the BSD socket APIs you will know that
getaddrinfo(3) returns a struct hostent, and that all the addrs in
struct hostent.h_addr_list are necessarily of the same family.

Generally, ruby's socket API reflects the system socket API, so I think
current behaviour is a bug.  It isn't a useful extension - a sockaddr
can't be used without knowing the type, and the second sockaddr is of
unspecified type.

The fix would be simple:

diff -u -r1.108.2.37 socket.c
--- socket.c  28 Nov 2005 09:56:45 -0000  1.108.2.37
+++ socket.c  30 Jan 2006 06:28:53 -0000
@@ -1250,7 +1250,14 @@
     rb_ary_push(ary, names);
     rb_ary_push(ary, INT2NUM(addr->ai_family));
     for (ai = addr; ai; ai = ai->ai_next) { 
+      /* Pushing all addresses regardless of address family is not the
+       * behaviour expected of gethostbyname(). All the addresses in struct
+       * hostent->h_addr_list must be of the same family, I think the following
+       * line would fix this.
+ 
+       if(ai->ai_family == addr->ai_family)  <-- suggested fix
+       */
        rb_ary_push(ary, (*ipaddr)(ai->ai_addr, ai->ai_addrlen));
     }
  
     return ary;

Cheers,
Sam


In This Thread

Prev Next