From ecb22ce2c54a635036031c2de70473d9daf4bfd5 Mon Sep 17 00:00:00 2001 From: akr Date: Thu, 26 Feb 2009 14:15:39 +0000 Subject: * 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 --- ext/socket/lib/socket.rb | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'ext') 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 #=> # + # serv.connect_address.connect {|c| + # s, _ = serv.accept + # p [c, s] #=> [#, #] + # } + # } + # + 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! -- cgit v1.2.3