зеркало из https://github.com/github/ruby.git
* ext/socket/lib/socket.rb (BasicSocket#connect_address): new method.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@22649 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
cbc7f1b89b
Коммит
ecb22ce2c5
|
@ -1,3 +1,7 @@
|
|||
Thu Feb 26 23:14:46 2009 Tanaka Akira <akr@fsij.org>
|
||||
|
||||
* ext/socket/lib/socket.rb (BasicSocket#connect_address): new method.
|
||||
|
||||
Thu Feb 26 19:29:10 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* hash.c (hash_foreach_iter): fix for prototype.
|
||||
|
|
1
NEWS
1
NEWS
|
@ -112,6 +112,7 @@ with all sufficient information, see the ChangeLog file.
|
|||
* Socket#ipv6only!
|
||||
* BasicSocket#local_address
|
||||
* BasicSocket#remote_address
|
||||
* BasicSocket#connect_address
|
||||
* BasicSocket#sendmsg
|
||||
* BasicSocket#sendmsg_nonblock
|
||||
* BasicSocket#recvmsg
|
||||
|
|
|
@ -158,6 +158,46 @@ class Addrinfo
|
|||
end
|
||||
end
|
||||
|
||||
class BasicSocket
|
||||
# Returns an address of the socket suitable for connect.
|
||||
#
|
||||
# This method returns _self_.local_address, except following condition.
|
||||
#
|
||||
# - IPv4 unspecified address (0.0.0.0) is replaced by IPv4 loopback address (127.0.0.1).
|
||||
# - IPv6 unspecified address (::) is replaced by IPv6 loopback address (::1).
|
||||
#
|
||||
# If the local address is not suitable for connect, SocketError is raised.
|
||||
# IPv4 and IPv6 address which port is 0 is not suitable for connect.
|
||||
# Unix domain socket which has no path is not suitable for connect.
|
||||
#
|
||||
# Addrinfo.tcp("0.0.0.0", 0).listen {|serv|
|
||||
# p serv.connect_address #=> #<Addrinfo: 127.0.0.1:53660 TCP>
|
||||
# serv.connect_address.connect {|c|
|
||||
# s, _ = serv.accept
|
||||
# p [c, s] #=> [#<Socket:fd 4>, #<Socket:fd 6>]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
def connect_address
|
||||
addr = local_address
|
||||
afamily = addr.afamily
|
||||
if afamily == Socket::AF_INET
|
||||
raise SocketError, "unbound IPv4 socket" if addr.ip_port == 0
|
||||
if addr.ip_address == "0.0.0.0"
|
||||
addr = Addrinfo.new(["AF_INET", addr.ip_port, nil, "127.0.0.1"], addr.pfamily, addr.socktype, addr.protocol)
|
||||
end
|
||||
elsif defined?(Socket::AF_INET6) && afamily == Socket::AF_INET6
|
||||
raise SocketError, "unbound IPv6 socket" if addr.ip_port == 0
|
||||
if addr.ip_address == "::"
|
||||
addr = Addrinfo.new(["AF_INET6", addr.ip_port, nil, "::1"], addr.pfamily, addr.socktype, addr.protocol)
|
||||
end
|
||||
elsif defined?(Socket::AF_UNIX) && afamily == Socket::AF_UNIX
|
||||
raise SocketError, "unbound Unix socket" if addr.unix_path == ""
|
||||
end
|
||||
addr
|
||||
end
|
||||
end
|
||||
|
||||
class Socket
|
||||
# enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available.
|
||||
def ipv6only!
|
||||
|
|
|
@ -73,22 +73,9 @@ class TestSocket < Test::Unit::TestCase
|
|||
}
|
||||
end
|
||||
|
||||
def tcp_unspecified_to_loopback(addrinfo)
|
||||
if addrinfo.ipv4? && addrinfo.ip_address == "0.0.0.0"
|
||||
Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
|
||||
elsif addrinfo.ipv6? && addrinfo.ipv6_unspecified?
|
||||
Addrinfo.tcp("::1", addrinfo.ip_port)
|
||||
elsif addrinfo.ipv6? && (ai = addrinfo.ipv6_to_ipv4) && ai.ip_address == "0.0.0.0"
|
||||
Addrinfo.tcp("127.0.0.1", addrinfo.ip_port)
|
||||
else
|
||||
addrinfo
|
||||
end
|
||||
end
|
||||
|
||||
def test_tcp
|
||||
TCPServer.open(0) {|serv|
|
||||
addr = serv.local_address
|
||||
addr = tcp_unspecified_to_loopback(addr)
|
||||
addr = serv.connect_address
|
||||
addr.connect {|s1|
|
||||
s2 = serv.accept
|
||||
begin
|
||||
|
@ -185,7 +172,7 @@ class TestSocket < Test::Unit::TestCase
|
|||
tcp_servers = Socket.tcp_server_sockets(0)
|
||||
unix_server = Socket.unix_server_socket("#{tmpdir}/sock")
|
||||
tcp_servers.each {|s|
|
||||
addr = tcp_unspecified_to_loopback(s.local_address)
|
||||
addr = s.connect_address
|
||||
clients << addr.connect
|
||||
}
|
||||
clients << unix_server.local_address.connect
|
||||
|
|
Загрузка…
Ссылка в новой задаче