From 5cfec5920a01b63d3b5383dcf955e0acdfe22873 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20H=C3=B6rberg?= Date: Sat, 20 Mar 2021 16:12:21 +0100 Subject: [PATCH 1/2] Use Ruby Resolv instead of LibC for hostname lookup This way DNS resolver can be replaced with: ```ruby Resolv::DefaultResolver.replace_resolvers [Resolv::DNS.new(nameserver: ['8.8.8.8']] ``` Related: #159, #184 --- lib/excon/socket.rb | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/lib/excon/socket.rb b/lib/excon/socket.rb index d2d256bf..0c09a57e 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] + hostname = @data[:proxy][:hostname] + port = @data[:proxy][:port] + family = @data[:proxy][:family] end - if RUBY_VERSION >= '1.9.2' && defined?(RUBY_ENGINE) && RUBY_ENGINE == 'ruby' - args << nil << nil << false # no reverse lookup - 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) From b3d3f896b37c68a6067e2048313f4befdd3c32fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20H=C3=B6rberg?= Date: Sat, 20 Mar 2021 16:48:39 +0100 Subject: [PATCH 2/2] Raise ResolvError if no hostnames were found --- lib/excon/socket.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/excon/socket.rb b/lib/excon/socket.rb index 0c09a57e..fa99fe94 100644 --- a/lib/excon/socket.rb +++ b/lib/excon/socket.rb @@ -107,7 +107,7 @@ def connect family = @data[:proxy][:family] end - ::Resolv.each_address(hostname) do |ip| + Resolv.each_address(hostname) do |ip| # already succeeded on previous addrinfo if @socket break @@ -150,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