I've documented class IPSocket, class Socket, and methods Socket.gethostbyname,
.getservbyname, and .getaddrinfo, but in doing so I noticed something quite
weird about Socket.gethostbyname.
Since Socket.gethostbyname doesn't have any docs, so its hard to know if what
it does is or is not a bug... but it doesn't behave like gethostbyname(3),
which is surprising. It can return multiple sockaddrs, this is expected, but
they are NOT all in the indicated address family!
On my system, os x 10.3, I can gets, for example:
["localhost", [], 30,
"\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\001",
"\177\000\000\001"]
and
["ensemble.local", [], 30,
"\376\200\000\004\000\000\000\000\002\003\223\377\376\255\010\214",
"\300\250{\232" ]
Note that getaddrinfo(3) returns a struct hostent, and there all the addrs in
struct hostent.h_addr_list are of the same family!
I'd like to have this clarified, the attached docs mention that this might be a
bug.
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) {
- rb_ary_push(ary, (*ipaddr)(ai->ai_addr, ai->ai_addrlen));
+ /* 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;
socket.diff
Description: Text document
|