socketry / async

An awesome asynchronous event-driven reactor for Ruby.
MIT License
2.09k stars 86 forks source link

SocketError: getaddrinfo: nodename nor servname provided, or not known #180

Closed conr closed 1 year ago

conr commented 1 year ago

Ruby version: 3.1.2 async: 2.1.0 async-http: 0.59.2 OS: macOS Monterey

Getting the following error and stack trace when making any HTTP calls.

The example below is when running this example from the async-http readme.

What's interesting is that everything works if I downgrade the async gem to 1.30.3 🤔

SocketError: getaddrinfo: nodename nor servname provided, or not known
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:770:in `ip'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:770:in `sender'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:527:in `block in fetch_resource'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:1125:in `block (3 levels) in resolv'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:1123:in `each'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:1123:in `block (2 levels) in resolv'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:1122:in `each'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:1122:in `block in resolv'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:1120:in `each'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:1120:in `resolv'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:521:in `fetch_resource'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:507:in `each_resource'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:402:in `each_address'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:116:in `block in each_address'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:115:in `each'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:115:in `each_address'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:102:in `getaddresses'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb:51:in `getaddresses'
/backend/vendor/bundle/ruby/3.1.0/gems/async-2.1.0/lib/async/scheduler.rb:139:in `address_resolve'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/socket.rb:227:in `getaddrinfo'
/.rbenv/versions/3.1.2/lib/ruby/3.1.0/socket.rb:227:in `foreach'
/backend/vendor/bundle/ruby/3.1.0/gems/async-io-1.34.0/lib/async/io/host_endpoint.rb:57:in `connect'
/backend/vendor/bundle/ruby/3.1.0/gems/async-io-1.34.0/lib/async/io/ssl_endpoint.rb:92:in `connect'
/backend/vendor/bundle/ruby/3.1.0/gems/async-http-0.59.2/lib/async/http/endpoint.rb:201:in `connect'
/backend/vendor/bundle/ruby/3.1.0/gems/async-http-0.59.2/lib/async/http/client.rb:199:in `block in make_pool'
/backend/vendor/bundle/ruby/3.1.0/gems/async-pool-0.3.12/lib/async/pool/controller.rb:249:in `create_resource'
/backend/vendor/bundle/ruby/3.1.0/gems/async-pool-0.3.12/lib/async/pool/controller.rb:300:in `get_resource'
/backend/vendor/bundle/ruby/3.1.0/gems/async-pool-0.3.12/lib/async/pool/controller.rb:266:in `block in available_resource'
/backend/vendor/bundle/ruby/3.1.0/gems/async-2.1.0/lib/async/semaphore.rb:66:in `acquire'
/backend/vendor/bundle/ruby/3.1.0/gems/async-pool-0.3.12/lib/async/pool/controller.rb:265:in `available_resource'
/backend/vendor/bundle/ruby/3.1.0/gems/async-pool-0.3.12/lib/async/pool/controller.rb:231:in `wait_for_resource'
/backend/vendor/bundle/ruby/3.1.0/gems/async-pool-0.3.12/lib/async/pool/controller.rb:82:in `acquire'
/backend/vendor/bundle/ruby/3.1.0/gems/async-http-0.59.2/lib/async/http/client.rb:106:in `call'
/backend/vendor/bundle/ruby/3.1.0/gems/protocol-http-0.23.12/lib/protocol/http/middleware.rb:50:in `call'
/backend/vendor/bundle/ruby/3.1.0/gems/protocol-http-0.23.12/lib/protocol/http/accept_encoding.rb:50:in `call'
/backend/vendor/bundle/ruby/3.1.0/gems/async-http-0.59.2/lib/async/http/internet.rb:67:in `call'
/backend/vendor/bundle/ruby/3.1.0/gems/async-http-0.59.2/lib/async/http/internet.rb:80:in `block (2 levels) in <class:Internet>'
/backend/lib/story_library/client.rb:42:in `block (2 levels) in get_stories'
/backend/vendor/bundle/ruby/3.1.0/gems/async-2.1.0/lib/async/task.rb:107:in `block in run'
/backend/vendor/bundle/ruby/3.1.0/gems/async-2.1.0/lib/async/task.rb:243:in `block in schedule'
ioquatix commented 1 year ago

SocketError: getaddrinfo: nodename nor servname provided, or not known

Are you sure the hostname is correct?

Can you tell me the request from client.rb:42?

Are you using a local dev DNS server?

conr commented 1 year ago

Are you sure the hostname is correct? Can you tell me the request from client.rb:42?

I was testing with the URL provided in the async-http readme: https://httpbin.org/anything Same deal if I use the actual URL or https://google.com etc.

Also tried with these benchmarking scripts and faced the same error.

Are you using a local dev DNS server?

Nope

ioquatix commented 1 year ago
#!/usr/bin/env ruby

require 'json'
require 'async'
require 'async/http'
require 'async/http/internet'

pp ASYNC_VERSION: Async::VERSION
pp ASYNC_HTTP_VERSION: Async::HTTP::VERSION
pp RUBY_VERSION: RUBY_VERSION
pp RUBY_PLATFORM: RUBY_PLATFORM

data = {'life' => 42}

Async do
    # Make a new internet:
    internet = Async::HTTP::Internet.new

    # Prepare the request:
    headers = [['accept', 'application/json']]
    body = [JSON.dump(data)]

    # Issues a POST request:
    response = internet.post("https://httpbin.org/anything", headers, body)

    # Save the response body to a local file:
    pp JSON.parse(response.read)
ensure
    # The internet is closed for business:
    internet.close
end

This is working fine for me on my M1 MacBook Pro. Are you on similar hardware?

Can you tell me what the following prints?

require 'io/event/selector'
pp IO::Event::Selector.default

For macOS it should be kqueue.

Can you try running the original code with the following change to resolv.rb:

        def sender(msg, data, host, port=Port)
          pp "Addrinfo.ip" => host                                       # Add this line!
          host = Addrinfo.ip(host).ip_address

When I run this code, I do not call this method, so something about your DNS might be different. Do you have any firewall or network tools running in the background that might be modifying or impacting your DNS resolution?

ioquatix commented 1 year ago

Can you also tell me the output of scutil --dns

conr commented 1 year ago

This is working fine for me on my M1 MacBook Pro. Are you on similar hardware?

I actually switched laptops yesterday to an Apple M1 Pro chip. Same error as before though.

Screenshot 2022-09-20 at 09 17 57

Can you tell me what the following prints?

require 'io/event/selector'
pp IO::Event::Selector.default

When I run the above I get: IO::Event::Selector::Select

Can you try running the original code with the following change to resolv.rb:

{"Addrinfo.ip"=>"fe80::1%en0"}

Do you have any firewall or network tools running in the background that might be modifying or impacting your DNS resolution?

I'm on a brand new machine now with the firewall in System Preferences enabled. I experimented by turning this off but it had no effect on the issue. I do not believe I have any network tools running in the background that may be impacting my DNS resolution.

Can you also tell me the output of scutil --dns

❯ scutil --dns
DNS configuration

resolver #1
  search domain[0] : home
  nameserver[0] : fe80::1%14d
  nameserver[1] : 192.168.1.254
  nameserver[2] : 192.168.1.254
  if_index : 14 (en0)
  flags    : Request A records, Request AAAA records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)

resolver #2
  domain   : local
  options  : mdns
  timeout  : 5
  flags    : Request A records, Request AAAA records
  reach    : 0x00000000 (Not Reachable)
  order    : 300000

resolver #3
  domain   : 254.169.in-addr.arpa
  options  : mdns
  timeout  : 5
  flags    : Request A records, Request AAAA records
  reach    : 0x00000000 (Not Reachable)
  order    : 300200

resolver #4
  domain   : 8.e.f.ip6.arpa
  options  : mdns
  timeout  : 5
  flags    : Request A records, Request AAAA records
  reach    : 0x00000000 (Not Reachable)
  order    : 300400

resolver #5
  domain   : 9.e.f.ip6.arpa
  options  : mdns
  timeout  : 5
  flags    : Request A records, Request AAAA records
  reach    : 0x00000000 (Not Reachable)
  order    : 300600

resolver #6
  domain   : a.e.f.ip6.arpa
  options  : mdns
  timeout  : 5
  flags    : Request A records, Request AAAA records
  reach    : 0x00000000 (Not Reachable)
  order    : 300800

resolver #7
  domain   : b.e.f.ip6.arpa
  options  : mdns
  timeout  : 5
  flags    : Request A records, Request AAAA records
  reach    : 0x00000000 (Not Reachable)
  order    : 301000

DNS configuration (for scoped queries)

resolver #1
  search domain[0] : home
  nameserver[0] : fe80::1%14d
  nameserver[1] : 192.168.1.254
  nameserver[2] : 192.168.1.254
  if_index : 14 (en0)
  flags    : Scoped, Request A records, Request AAAA records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)
ioquatix commented 1 year ago

Do you have Xcode and compiler tools installed? The select backend is probably not working correctly I this specific case. I'll check it. Because you may not have the developer tools installed, it can't compile the kqueue backend.

conr commented 1 year ago

Do you have Xcode and compiler tools installed?

I have Xcode Command Line Tools installed. I don't have Xcode itself installed (installing now).

ioquatix commented 1 year ago

Can you please reinstall the io-event gem and check what selector is used by default? On macOS it should be kqueue.

conr commented 1 year ago

Can you please reinstall the io-event gem and check what selector is used by default? On macOS it should be kqueue.

Not getting kqueue unfortunately (Xcode installed now):

Screenshot 2022-09-20 at 12 36 52

ioquatix commented 1 year ago

Can you checkout the code for io-event, bundle update and bake build then show me the output? Thanks!

conr commented 1 year ago

Can you checkout the code for io-event, bundle update and bake build then show me the output? Thanks!

❯ bake build
checking for rb_ext_ractor_safe()... yes
checking for &rb_fiber_transfer()... yes
checking for -luring... no
checking for sys/epoll.h... no
checking for sys/event.h... yes
checking for sys/eventfd.h... no
checking for rb_io_descriptor()... yes
checking for &rb_process_status_wait()... no
checking for rb_fiber_current()... yes
checking for &rb_fiber_raise()... yes
checking for ruby/io/buffer.h... yes
creating extconf.h
creating Makefile
compiling ./io/event/event.c
compiling ./io/event/selector/selector.c
compiling ./io/event/selector/kqueue.c
compiling ./io/event/interrupt.c
linking shared-object IO_Event.bundle
ld: warning: -undefined dynamic_lookup may not work with chained fixups
~/src/io-event main* ❯
ioquatix commented 1 year ago

Can you tell me the output of arch in your terminal?

conr commented 1 year ago

Can you tell me the output of arch in your terminal?

Sure, it's arm64

ioquatix commented 1 year ago

Can you try this:

irb(main):001:0> require 'io/event'
=> true
irb(main):002:0> IO::Event::Selector.default
=> IO::Event::Selector::KQueue

Do you get KQueue?

conr commented 1 year ago

Do you get KQueue?

I do indeed

Screenshot 2022-09-21 at 11 17 36

ioquatix commented 1 year ago

Can you try running the original code with the following change to resolv.rb:

        def sender(msg, data, host, port=Port)
          pp "Addrinfo.ip" => host                                       # Add this line!
          host = Addrinfo.ip(host).ip_address

In your system, it should be .rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb

Then tell me the host.

conr commented 1 year ago

Can you try running the original code with the following change to resolv.rb:

        def sender(msg, data, host, port=Port)
          pp "Addrinfo.ip" => host                                       # Add this line!
          host = Addrinfo.ip(host).ip_address

In your system, it should be .rbenv/versions/3.1.2/lib/ruby/3.1.0/resolv.rb

Then tell me the host.

{"Addrinfo.ip"=>"fe80::1%en0"}

(Apologies for the late response!)

ioquatix commented 1 year ago

That's okay, it confirms what I found out in the linked issue, something is wrong with IPv6 addresses in resolv.rb - I can test this out and should be able to repro/fix.

conr commented 1 year ago

Thanks for fixing 😄

ioquatix commented 1 year ago

Do you mind testing it? I just released v2.6.0.

conr commented 1 year ago

Looks like my error has changed but I'll likely need to update my code as I've been pinned to version 1.30.3

image

ioquatix commented 1 year ago

It looks like you are opening too many files, you need to increase your ulimit.

e.g. https://stackoverflow.com/questions/33773237/open-more-server-sockets-than-in-ulimit-n