def connect(timeout=nil)
disconnect("reconnecting") if connected?
host, port = @destinations.first.split(":")
@destinations = @destinations.rotate
addresses = FTW::DNS.singleton.resolve(host)
addresses.each do |address|
@remote_address = address
family = @remote_address.include?(":") ? Socket::AF_INET6 : Socket::AF_INET
@logger.debug("Connecting", :address => @remote_address,
:host => host, :port => port, :family => family)
@socket = Socket.new(family, Socket::SOCK_STREAM, 0)
@socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1)
@logger.debug("packing", :data => [port.to_i, @remote_address])
sockaddr = Socket.pack_sockaddr_in(port.to_i, @remote_address)
begin
@socket.connect_nonblock(sockaddr)
rescue IO::WaitWritable, Errno::EINPROGRESS
writable = writable?(timeout)
if writable || (RUBY_PLATFORM == "java" and JRUBY_VERSION < "1.7.0")
begin
@socket.connect_nonblock(sockaddr)
rescue Errno::EISCONN
rescue Errno::ECONNREFUSED => e
@socket.close
return ConnectRefused.new("#{host}[#{@remote_address}]:#{port}")
rescue Errno::ETIMEDOUT
@socket.close
return ConnectTimeout.new("#{host}[#{@remote_address}]:#{port}")
rescue Errno::EINPROGRESS
@socket.close
return ConnectTimeout.new("#{host}[#{@remote_address}]:#{port}")
end
else
return ConnectTimeout.new("#{host}[#{@remote_address}]:#{port}")
end
@connected = true
break
end
end
return nil
end