diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-26 14:15:39 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2009-02-26 14:15:39 +0000 |
commit | ecb22ce2c54a635036031c2de70473d9daf4bfd5 (patch) | |
tree | ce44ae2d1b16ff12f219ade35e548432919ce328 /ext/socket | |
parent | cbc7f1b89bee06ccad0915821762c41251a97aff (diff) | |
download | ruby-ecb22ce2c54a635036031c2de70473d9daf4bfd5.tar.gz |
* 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
Diffstat (limited to 'ext/socket')
-rw-r--r-- | ext/socket/lib/socket.rb | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/ext/socket/lib/socket.rb b/ext/socket/lib/socket.rb index f83e9d6e05..8a5e180f55 100644 --- a/ext/socket/lib/socket.rb +++ b/ext/socket/lib/socket.rb @@ -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! |