diff --git a/lib/excon/socket.rb b/lib/excon/socket.rb index e5b53695..a6d99a99 100644 --- a/lib/excon/socket.rb +++ b/lib/excon/socket.rb @@ -1,4 +1,6 @@ # frozen_string_literal: true +require 'resolv' + module Excon class Socket include Utils @@ -95,20 +97,17 @@ def local_port def connect @socket = nil exception = nil + hostname = @data[:hostname] + port = @port + family = @data[:family] if @data[:proxy] - family = @data[:proxy][:family] || ::Socket::Constants::AF_UNSPEC - args = [@data[:proxy][:hostname], @data[:proxy][:port], family, ::Socket::Constants::SOCK_STREAM] - else - family = @data[:family] || ::Socket::Constants::AF_UNSPEC - args = [@data[:hostname], @port, family, ::Socket::Constants::SOCK_STREAM] - end - if RUBY_VERSION >= '1.9.2' && defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' - args << nil << nil << false # no reverse lookup + hostname = @data[:proxy][:hostname] + port = @data[:proxy][:port] + family = @data[:proxy][:family] end - addrinfo = ::Socket.getaddrinfo(*args) - addrinfo.each do |_, port, _, ip, a_family, s_type| + Resolv.each_address(hostname) do |ip| # already succeeded on previous addrinfo if @socket break @@ -120,8 +119,8 @@ def connect # nonblocking connect begin sockaddr = ::Socket.sockaddr_in(port, ip) - - socket = ::Socket.new(a_family, s_type, 0) + addrinfo = Addrinfo.getaddrinfo(ip, port, family, :STREAM).first + socket = ::Socket.new(addrinfo.pfamily, addrinfo.socktype, addrinfo.protocol) if @data[:reuseaddr] socket.setsockopt(::Socket::Constants::SOL_SOCKET, ::Socket::Constants::SO_REUSEADDR, true) @@ -151,6 +150,8 @@ def connect end end + exception ||= Resolv::ResolvError.new("no address for #{hostname}") + # this will be our last encountered exception fail exception unless @socket