def initialize(remote_host, remote_port = nil, local_host = nil, local_port = nil)
super()
if remote_host.is_a? ::TCPSocket
@addr = nil
@socket = remote_host
return
elsif remote_port.nil?
raise ArgumentError, "wrong number of arguments (1 for 2)"
end
begin
@addr = Resolv::IPv4.create(remote_host)
rescue ArgumentError
end
unless @addr
begin
@addr = Resolv::IPv6.create(remote_host)
rescue ArgumentError
end
end
unless @addr
addrs = Array(DNSResolver.new.resolve(remote_host))
raise Resolv::ResolvError, "DNS result has no information for #{remote_host}" if addrs.empty?
@addr = addrs[rand(addrs.size)]
end
case @addr
when Resolv::IPv4
family = Socket::AF_INET
when Resolv::IPv6
family = Socket::AF_INET6
else raise ArgumentError, "unsupported address class: #{@addr.class}"
end
@socket = Socket.new(family, Socket::SOCK_STREAM, 0)
@socket.bind Addrinfo.tcp(local_host, local_port) if local_host
begin
@socket.connect_nonblock Socket.sockaddr_in(remote_port, @addr.to_s)
rescue Errno::EINPROGRESS
wait_writable
retry unless defined?(JRUBY_VERSION) && @socket.to_channel.finish_connect
rescue Errno::EISCONN
end
end