mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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:
parent
cbc7f1b89b
commit
ecb22ce2c5
4 changed files with 47 additions and 15 deletions
|
@ -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>
|
Thu Feb 26 19:29:10 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||||
|
|
||||||
* hash.c (hash_foreach_iter): fix for prototype.
|
* 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!
|
* Socket#ipv6only!
|
||||||
* BasicSocket#local_address
|
* BasicSocket#local_address
|
||||||
* BasicSocket#remote_address
|
* BasicSocket#remote_address
|
||||||
|
* BasicSocket#connect_address
|
||||||
* BasicSocket#sendmsg
|
* BasicSocket#sendmsg
|
||||||
* BasicSocket#sendmsg_nonblock
|
* BasicSocket#sendmsg_nonblock
|
||||||
* BasicSocket#recvmsg
|
* BasicSocket#recvmsg
|
||||||
|
|
|
@ -158,6 +158,46 @@ class Addrinfo
|
||||||
end
|
end
|
||||||
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
|
class Socket
|
||||||
# enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available.
|
# enable the socket option IPV6_V6ONLY if IPV6_V6ONLY is available.
|
||||||
def ipv6only!
|
def ipv6only!
|
||||||
|
|
|
@ -73,22 +73,9 @@ class TestSocket < Test::Unit::TestCase
|
||||||
}
|
}
|
||||||
end
|
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
|
def test_tcp
|
||||||
TCPServer.open(0) {|serv|
|
TCPServer.open(0) {|serv|
|
||||||
addr = serv.local_address
|
addr = serv.connect_address
|
||||||
addr = tcp_unspecified_to_loopback(addr)
|
|
||||||
addr.connect {|s1|
|
addr.connect {|s1|
|
||||||
s2 = serv.accept
|
s2 = serv.accept
|
||||||
begin
|
begin
|
||||||
|
@ -185,7 +172,7 @@ class TestSocket < Test::Unit::TestCase
|
||||||
tcp_servers = Socket.tcp_server_sockets(0)
|
tcp_servers = Socket.tcp_server_sockets(0)
|
||||||
unix_server = Socket.unix_server_socket("#{tmpdir}/sock")
|
unix_server = Socket.unix_server_socket("#{tmpdir}/sock")
|
||||||
tcp_servers.each {|s|
|
tcp_servers.each {|s|
|
||||||
addr = tcp_unspecified_to_loopback(s.local_address)
|
addr = s.connect_address
|
||||||
clients << addr.connect
|
clients << addr.connect
|
||||||
}
|
}
|
||||||
clients << unix_server.local_address.connect
|
clients << unix_server.local_address.connect
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue