summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--mrblib/socket.rb50
-rw-r--r--test/ipsocket.rb40
-rw-r--r--test/socket.rb13
3 files changed, 82 insertions, 21 deletions
diff --git a/mrblib/socket.rb b/mrblib/socket.rb
index b04375f60..d103dbf1d 100644
--- a/mrblib/socket.rb
+++ b/mrblib/socket.rb
@@ -139,6 +139,21 @@ class Addrinfo
attr_reader :protocol
attr_reader :socktype
+ def _to_array
+ case @family
+ when Socket::AF_INET
+ s = "AF_INET"
+ when Socket::AF_INET6
+ s = "AF_INET6"
+ when Socket::AF_UNIX
+ s = "AF_UNIX"
+ else
+ s = "(unknown AF)"
+ end
+ addr, port = self.getnameinfo(Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)
+ [ s, port.to_i, addr, addr ]
+ end
+
def to_sockaddr
@sockaddr
end
@@ -189,35 +204,21 @@ class BasicSocket
end
class IPSocket
- def self.getddress(host)
+ def self.getaddress(host)
Addrinfo.ip(host).ip_address
end
- def _ai_to_array(ai)
- case ai.afamily
- when Socket::AF_INET
- s = "AF_INET"
- when Socket::AF_INET6
- s = "AF_INET6"
- when Socket::AF_UNIX
- s = "AF_UNIX"
- else
- s = "(unknown AF)"
- end
- [ s, ai.ip_port, ai.ip_address, ai.ip_address ]
- end
-
def addr
- _ai_to_array(Addrinfo.new(self.getsockname))
+ Addrinfo.new(self.getsockname)._to_array
end
def peeraddr
- _ai_to_array(Addrinfo.new(self.getpeername))
+ Addrinfo.new(self.getpeername)._to_array
end
def recvfrom(maxlen, flags=0)
msg, sa = _recvfrom(maxlen, flags)
- [ msg, _ai_to_array(Addrinfo.new(sa)) ]
+ [ msg, Addrinfo.new(sa)._to_array ]
end
end
@@ -328,9 +329,16 @@ class Socket
#def self.accept_loop
- # def self.getaddrinfo
- # by Addrinfo.getaddrinfo
- #end
+ def self.getaddrinfo(nodename, servname, family=nil, socktype=nil, protocol=nil, flags=0)
+ Addrinfo.getaddrinfo(nodename, servname, family, socktype, protocol, flags).map { |ai|
+ ary = ai._to_array
+ ary[2] = nodename
+ ary[4] = ai.afamily
+ ary[5] = ai.socktype
+ ary[6] = ai.protocol
+ ary
+ }
+ end
#def self.getnameinfo
#def self.ip_address_list
diff --git a/test/ipsocket.rb b/test/ipsocket.rb
new file mode 100644
index 000000000..2b9f7e1d7
--- /dev/null
+++ b/test/ipsocket.rb
@@ -0,0 +1,40 @@
+# Note: most of tests below will fail if UDPSocket is broken.
+
+assert('IPSocket.getaddress') do
+ l = IPSocket.getaddress("localhost")
+ assert_true (l == "127.0.0.1" or l == "::1")
+end
+
+assert('IPSocket.addr') do
+ localhost = "127.0.0.1"
+ s = UDPSocket.new
+ s.bind(localhost, 0)
+ port = Addrinfo.new(s.getsockname).ip_port
+
+ a = s.addr
+ assert_equal "AF_INET", a[0]
+ assert_equal port, a[1]
+ assert_equal localhost, a[2]
+ assert_equal localhost, a[3]
+ s.close
+ true
+end
+
+assert('IPSocket.peeraddr') do
+ localhost = "127.0.0.1"
+ server = UDPSocket.new
+ server.bind(localhost, 0)
+ port = server.local_address.ip_port
+
+ client = UDPSocket.new
+ client.connect(localhost, port)
+
+ a = client.peeraddr
+ assert_equal "AF_INET", a[0]
+ assert_equal port, a[1]
+ assert_equal localhost, a[2]
+ assert_equal localhost, a[3]
+ client.close
+ server.close
+ true
+end
diff --git a/test/socket.rb b/test/socket.rb
index 309e7cf11..cd50cbaff 100644
--- a/test/socket.rb
+++ b/test/socket.rb
@@ -133,3 +133,16 @@ assert('Socket.gethostname') do
assert_true(Socket.gethostname.is_a? String)
end
+assert('Socket::getaddrinfo') do
+ ret = Socket.getaddrinfo("localhost", "domain", 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]
+end