Files
Yukihiro "Matz" Matsumoto 43c0b50cbd mruby-socket: implement Socket.ip_address_list
Returns an Array of Addrinfo objects for all local IP addresses
(IPv4 and IPv6) on every network interface, matching CRuby's API.

Backed by getifaddrs(3) on POSIX and GetAdaptersAddresses on
Windows (requires iphlpapi.lib, added to the Windows linker libs).
The HAL returns binary sockaddr strings; src/socket.c wraps each
into Addrinfo so the wrapping code stays platform-agnostic.

Resolves the second error reported in #5659 (after the IO.select
fix from the HAL split): "undefined method 'ip_address_list' for
Class". Issue #5659 itself is closed; this lands the missing API.

Ref #5659.

Co-authored-by: Claude <noreply@anthropic.com>
2026-05-09 10:22:19 +09:00

53 lines
1.6 KiB
Ruby

unless SocketTest.win?
assert('Socket.gethostname') do
assert_true(Socket.gethostname.is_a? String)
end
assert('Socket::getaddrinfo') do
ret = Socket.getaddrinfo("localhost", 53, Socket::AF_INET, Socket::SOCK_DGRAM)
assert_true ret.size >= 1
a = ret[0]
assert_equal "AF_INET", a[0]
assert_equal 53, a[1]
# documents says it's a hostname but CRuby returns an address
#assert_equal "127.0.0.1", a[2]
assert_equal "127.0.0.1", a[3]
assert_equal Socket::AF_INET, a[4]
assert_equal Socket::SOCK_DGRAM, a[5]
assert_equal Socket::IPPROTO_UDP, a[6] unless SocketTest.cygwin?
end
assert('Socket#recvfrom') do
begin
sstr = "abcdefg"
s = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
c = Socket.new(Socket::AF_INET, Socket::SOCK_DGRAM, 0)
s.bind(Socket.sockaddr_in(0, "127.0.0.1"))
c.send sstr, 0, s.getsockname
rstr, ai = s.recvfrom sstr.size
assert_equal sstr, rstr
assert_equal "127.0.0.1", ai.ip_address
ensure
s.close rescue nil
c.close rescue nil
end
end
end # win?
# Socket.ip_address_list works on both POSIX (getifaddrs) and Windows
# (GetAdaptersAddresses), so this test runs everywhere.
assert('Socket.ip_address_list') do
list = Socket.ip_address_list
assert_kind_of Array, list
# Every host should have at least one address (loopback at minimum).
assert_true list.length >= 1
list.each do |ai|
assert_kind_of Addrinfo, ai
# Only AF_INET and AF_INET6 are returned.
assert_true [Socket::AF_INET, Socket::AF_INET6].include?(ai.afamily)
end
end