Bug #743
closedSocket.gethostbyname returns odd values
Description
ruby -rsocket -e 'p Socket.gethostbyname("127.0.0.1")'
should return something like ["localhost", [], 2, "\177\000\000\001"]
(it does with ruby 1.8.2 (2005-04-11) and also on windows)
However, on linux with 1.9/1.8.7 it returns
["127.0.0.1", [], 2, "\x7F\x00\x00\x01"]
Socket.gethostbyname("127.0.0.1")'
["127.0.0.1", [], 2, "\177\000\000\001"]
respectively, which I think is unexpected.
Thanks!
from
=end
Files
Updated by usa (Usaku NAKAMURA) over 16 years ago
- Category set to ext
- Assignee set to usa (Usaku NAKAMURA)
=begin
=end
Updated by usa (Usaku NAKAMURA) over 16 years ago
- Assignee deleted (
usa (Usaku NAKAMURA))
=begin
=end
Updated by candlerb (Brian Candler) over 16 years ago
=begin
But:
$ ruby19 -rsocket -e 'p Socket.gethostbyname("localhost")'
["localhost", [], 2, "\x7F\x00\x00\x01"]
(ditto 1.8.6)
If Ruby has been changed so that it doesn't do a reverse DNS lookup when given an IP address to gethostbyname, then I support this change.
(1) It causes all sorts of problems and delays where reverse DNS isn't set up properly, e.g. with druby://x.x.x.x/ where x.x.x.x is an IP address.
I have on many occasions had to do
Socket.do_not_reverse_lookup = true
just to allow this to work properly.
(2) I found this annoying because I never asked for a reverse DNS lookup, and yet one was forced on me.
(3) I found this surprising, because the stdlib gethostbyname() doesn't do a reverse lookup.
=end
Updated by alanwj (Alan Johnson) over 16 years ago
- File bug743.patch bug743.patch added
=begin
gethostbyname/gethostbyaddr seem to work oddly in many respects.
- Socket.gethostbyname works differently than TCPSocket.gethostbyname. The latter doesn't seem to have any real purpose for existing.
- The alias array is always empty.
- When a host has multiple IP addresses, they are tacked onto the end of the array. To more faithfully represent a struct hostent, the fourth array member should itself be an array of addresses (matching h_addr_list).
These problems mostly seem to stem from the fact that instead of faithfully calling the underlying library implementation, they ALSO call getaddrinfo.
The least surprising effect of calling gethostbyname or gethostbyaddr would be for it to just call the underlying library implementation. That means that gethostbyname should not do a reverse lookup, and if you want a reverse lookup you should call gethostbyaddr or one of the other functions that does such a lookup. This is partially impeded by the fact that gethostbyaddr requires an struct in_addr parameter packed into a ruby string. This suggests that Socket also needs to implement inet_aton (and inet_ntoa just for symmetry).
I'm attaching a patch that does the following:
- Remove TCPSocket.gethostbyname
- Implement Socket.gethostbyname and Socket.gethostbyaddr as calls to the underlying library implementations.
- Make the fourth member of the result array of the above functions an array matching struct hostent's h_addr_list member.
- Implement Socket.inet_aton and Socket.inet_ntoa.
Subsequently code similar to the following will be possible:
require 'socket'
def print_hostent(hostent)
hostname, aliases, family, addresses = hostent
print "Hostname: #{hostname}\n"
print "Aliases:\n"
aliases.each { |a| print " #{a}\n" }
print "Addresses:\n"
addresses.each { |addr| print " #{Socket.inet_ntoa(addr)}\n" }
end
hostent = Socket.gethostbyname('www.ruby-lang.org')
print_hostent hostent
print "\n"
hostent = Socket.gethostbyaddr(Socket.inet_aton("221.186.184.68"))
print_hostent hostent
$ ruby19 example.rb
Hostname: carbon.ruby-lang.org
Aliases:
www.ruby-lang.org
Addresses:
221.186.184.68
Hostname: carbon.ruby-lang.org
Aliases:
Addresses:
221.186.184.68
=end
Updated by rogerdpack (Roger Pack) over 16 years ago
=begin
Does this require you to now use Socket.inet_ntoa ? That seems kind of stepping backward...then again, I am a little inherently lazy :)
Thanks!
-=R
=end
Updated by alanwj (Alan Johnson) over 16 years ago
=begin
If adding back a TCPSocket.gethostbyname that eliminated that step got this patch accepted I'd be happy to do that. I still believe that gethostbyname/gethostbyaddr should behave like their POSIX namesakes, and that returning the addresses as an array makes more sense than pushing them all into the containing array.
=end
Updated by matz (Yukihiro Matsumoto) over 16 years ago
=begin
Hi,
In message "Re: [ruby-core:19989] [Bug #743] Socket.gethostbyname returns odd values"
on Wed, 19 Nov 2008 18:58:25 +0900, Alan Johnson [email protected] writes:
|File bug743.patch added
|
|gethostbyname/gethostbyaddr seem to work oddly in many respects.
|
|1) Socket.gethostbyname works differently than TCPSocket.gethostbyname. The latter doesn't seem to have any real purpose for existing.
|2) The alias array is always empty.
|3) When a host has multiple IP addresses, they are tacked onto the end of the array. To more faithfully represent a struct hostent, the fourth array member should itself be an array of addresses (matching h_addr_list).
|
|These problems mostly seem to stem from the fact that instead of faithfully calling the underlying library implementation, they ALSO call getaddrinfo.
It's implemented using getaddrinfo because at the time of coding (long
ago) it was virtually only way to support IPv6 addresses. And you
patch seems destruct IPv6 support. I'd happy to address above issues,
but we are not going to disable IPv6 support.
matz.
=end
Updated by matz (Yukihiro Matsumoto) over 16 years ago
- Status changed from Open to Rejected
=begin
I think you have to do reverse lookup explicitly.
And I couldn't merge the "fix" patch since it disables IPv6 support.
=end
Updated by alanwj (Alan Johnson) over 16 years ago
=begin
On Wed, Nov 26, 2008 at 5:04 PM, Yukihiro Matsumoto [email protected] wrote:
Hi,
In message "Re: [ruby-core:19989] [Bug #743] Socket.gethostbyname returns odd values"
on Wed, 19 Nov 2008 18:58:25 +0900, Alan Johnson [email protected] writes:|File bug743.patch added
|
|gethostbyname/gethostbyaddr seem to work oddly in many respects.
|
|1) Socket.gethostbyname works differently than TCPSocket.gethostbyname. The latter doesn't seem to have any real purpose for existing.
|2) The alias array is always empty.
|3) When a host has multiple IP addresses, they are tacked onto the end of the array. To more faithfully represent a struct hostent, the fourth array member should itself be an array of addresses (matching h_addr_list).
|
|These problems mostly seem to stem from the fact that instead of faithfully calling the underlying library implementation, they ALSO call getaddrinfo.It's implemented using getaddrinfo because at the time of coding (long
ago) it was virtually only way to support IPv6 addresses. And you
patch seems destruct IPv6 support. I'd happy to address above issues,
but we are not going to disable IPv6 support.matz.
(Replying via mailing list because the topic has strayed from that of
the bug report.)
Forgive me if this sounds like a stupid question ... why do you care
about ipv6 support in gethostbyname/gethostbyaddr? These functions
(the POSIX ones, not ruby) are known for having poor ipv6 support,
which is a major reason why getaddrinfo/getnameinfo exist, and those
should be the preferred methods used by anyone needing ipv6. Trying
to retroactively add support to gethostbyname leads to nonsensical
results like the following:
irb(main):002:0> Socket.gethostbyname('host1.example.com')
=> ["host1.example.com", [], 2, "\xC0\xA8\x01\x02",
"\xC0\xA8\x01\x03", "\xC0\xA8\x01\x01",
"\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01",
"\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02",
"\xFC\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03"]
Note that the address family is reported as 2 (AF_INET) but three of
the results do not belong in that address family.
As I understand it, the Socket class exists to provide low level
support for the underlying socket implementation. It is confusing for
Ruby's implementation of a function to behave differently from the
platform's implementation.
--
Alan
=end
Updated by matz (Yukihiro Matsumoto) over 16 years ago
=begin
Hi,
In message "Re: [ruby-core:20154] Re: [Bug #743] Socket.gethostbyname returns odd values"
on Sat, 29 Nov 2008 04:21:54 +0900, "Alan Johnson" [email protected] writes:
|Forgive me if this sounds like a stupid question ... why do you care
|about ipv6 support in gethostbyname/gethostbyaddr? These functions
|(the POSIX ones, not ruby) are known for having poor ipv6 support,
|which is a major reason why getaddrinfo/getnameinfo exist, and those
|should be the preferred methods used by anyone needing ipv6.
It's to help IPv6 transition. Ordinary programmers still tend to use
gethostbyname in their programs. Making these programs IPv6 ready
easier is more important than being compatible with underlying
functions of the platforms. I assume that is/was the intention of the
original author (Itojun), who was an IPv6 Guru and had passed away
last year.
matz.
=end
Updated by rogerdpack (Roger Pack) over 16 years ago
=begin
So returning to the original "oddity" that Socket.gethostbyname returns different parameters in Linux/Windows--is this expected/desired?
=end
Updated by matz (Yukihiro Matsumoto) over 16 years ago
=begin
Hi,
In message "Re: [ruby-core:20417] [Bug #743] Socket.gethostbyname returns odd values"
on Mon, 8 Dec 2008 18:50:20 +0900, Roger Pack [email protected] writes:
|So returning to the original "oddity" that Socket.gethostbyname returns different parameters in Linux/Windows--is this expected/desired?
I am not sure if it's desired or not, but it follows underlying
library implementation (of getaddrbyname), and it's within (my)
expectation. If it's not desirable, tell us.
matz.
=end