ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:102614] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers
@ 2021-02-26  9:32 mcarpenter
  2021-02-26  9:38 ` [ruby-core:102615] " mcarpenter
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: mcarpenter @ 2021-02-26  9:32 UTC (permalink / raw)
  To: ruby-core

Issue #17658 has been reported by mcarpenter (Martin Carpenter).

----------------------------------------
Bug #17658: DNS resolution failure with multiple named resolvers
https://bugs.ruby-lang.org/issues/17658

* Author: mcarpenter (Martin Carpenter)
* Status: Open
* Priority: Normal
* ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
## Description

I created a `Resolv::DNS` resolver with two nameservers described using their domain names. Calling `#getresources` on this for an `A` or `NS` (and possibly other resource types) of domain `example.com` returns an empty list (no results, no error). I expected it to return the corresponding resource record (IP of `example.com`).

Instead if the `Resolv::DNS` instance is created with one resolver domain name or two resolvers' IP addresses then correct results are obtained. The error occurs only when more than two nameservers [or possibly more] are specified using their domain names.

## Testcases

I used two well-known public DNS servers to test (they have funky but legitimate TLDs):
 * dns.google (8.8.4.4, 8.8.8.8)
 * one.one.one.one (1.1.1.1, 1.0.0.1)

### ✗ Failing: two nameservers by name
```ruby
require 'resolv'
Resolv::DNS.new({nameserver: ['dns.google', 'one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> []
```

### ✓ Successful: one nameserver by name
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: 'dns.google'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95df9ad8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=16840>]
Resolv::DNS.new({nameserver: ['one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95517c80 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=77160>]
```

### ✓ Successful: one nameserver by IP
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e28d38 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20931>]
Resolv::DNS.new({nameserver: '1.1.1.1'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e41360 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=66081>]
```

### ✓ Successful: two nameservers by IP
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4', '1.1.1.1']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95d62ea8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20894>]
```

## A little analysis

I didn't get to the bottom of this but this may help:
 * When only one nameserver is used then a `Resolv::DNS::Requester::ConnectedUDP::Sender` is used; when two nameservers are used an `UnconnectedUDP::Sender` is used.
 * The code appears to be timing out and then retried even though correct requests are made and responses received.
 * In particular, if I packet trace 53/udp then the conversation is exactly as I would expect and near identical in both failing and successful cases. That is:
   * Request A record for first nameserver from local resolver
   * Receive IP of first nameserver
   * Request A record of `example.com` from first nameserver
   * Receive IP of `example.com`
   In the successful case, the conversation ends here. In the failing case, the code round-robins between the two nameservers until it finally returns `[]`.


## Test environment

Tested ruby 2.5.0p0 on Red Hat 6 and rubies 2.7.1p83, 2.7.2p137 on Ubuntu 20 from two different networks with identical results.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:102615] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers
  2021-02-26  9:32 [ruby-core:102614] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers mcarpenter
@ 2021-02-26  9:38 ` mcarpenter
  2021-02-26 10:04 ` [ruby-core:102616] " mcarpenter
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: mcarpenter @ 2021-02-26  9:38 UTC (permalink / raw)
  To: ruby-core

Issue #17658 has been updated by mcarpenter (Martin Carpenter).


I tested ruby 3.0.0 and it works fine so I guess something got fixed:

```ruby
Resolv::DNS.new({nameserver: ['dns.google', 'one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x00005630d981e268 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=17981>]
```

(`ruby 3.0.0p0 (2020-12-25 revision 95aff21468) [x86_64-linux]`)


----------------------------------------
Bug #17658: DNS resolution failure with multiple named resolvers
https://bugs.ruby-lang.org/issues/17658#change-90602

* Author: mcarpenter (Martin Carpenter)
* Status: Open
* Priority: Normal
* ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
## Description

I created a `Resolv::DNS` resolver with two nameservers described using their domain names. Calling `#getresources` on this for an `A` or `NS` (and possibly other resource types) of domain `example.com` returns an empty list (no results, no error). I expected it to return the corresponding resource record (IP of `example.com`).

Instead if the `Resolv::DNS` instance is created with one resolver domain name or two resolvers' IP addresses then correct results are obtained. The error occurs only when more than two nameservers [or possibly more] are specified using their domain names.

## Testcases

I used two well-known public DNS servers to test (they have funky but legitimate TLDs):
 * dns.google (8.8.4.4, 8.8.8.8)
 * one.one.one.one (1.1.1.1, 1.0.0.1)

### ✗ Failing: two nameservers by name
```ruby
require 'resolv'
Resolv::DNS.new({nameserver: ['dns.google', 'one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> []
```

### ✓ Successful: one nameserver by name
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: 'dns.google'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95df9ad8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=16840>]
Resolv::DNS.new({nameserver: ['one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95517c80 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=77160>]
```

### ✓ Successful: one nameserver by IP
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e28d38 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20931>]
Resolv::DNS.new({nameserver: '1.1.1.1'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e41360 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=66081>]
```

### ✓ Successful: two nameservers by IP
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4', '1.1.1.1']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95d62ea8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20894>]
```

## A little analysis

I didn't get to the bottom of this but this may help:
 * When only one nameserver is used then a `Resolv::DNS::Requester::ConnectedUDP::Sender` is used; when two nameservers are used an `UnconnectedUDP::Sender` is used.
 * The code appears to be timing out and then retried even though correct requests are made and responses received.
 * In particular, if I packet trace 53/udp then the conversation is exactly as I would expect and near identical in both failing and successful cases. That is:
   * Request A record for first nameserver from local resolver
   * Receive IP of first nameserver
   * Request A record of `example.com` from first nameserver
   * Receive IP of `example.com`
   In the successful case, the conversation ends here. In the failing case, the code round-robins between the two nameservers until it finally returns `[]`.


## Test environment

Tested ruby 2.5.0p0 on Red Hat 6 and rubies 2.7.1p83, 2.7.2p137 on Ubuntu 20 from two different networks with identical results.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:102616] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers
  2021-02-26  9:32 [ruby-core:102614] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers mcarpenter
  2021-02-26  9:38 ` [ruby-core:102615] " mcarpenter
@ 2021-02-26 10:04 ` mcarpenter
  2021-03-20  4:19 ` [ruby-core:102937] " nagachika00
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: mcarpenter @ 2021-02-26 10:04 UTC (permalink / raw)
  To: ruby-core

Issue #17658 has been updated by mcarpenter (Martin Carpenter).


Fixing commit is below.

#12838 states that the problem is intermittent and due to duplicate responses. That's not what I have observed: I can consistently reproduce the problem. Can this one-line change + test please be back-ported to 2.x?

```commit
commit 9682db065158da5fa4ec8a3bc267da45b429b92c
Author: Jeremy Evans <code@jeremyevans.net>
Date:   Fri Sep 11 14:28:20 2020 -0700

    Remove sender/message_id pair after response received in resolv
    
    Once a response for a given DNS request has been received (which
    requires a matching message id), the [sender, message_id] pair
    should be removed from the list of valid senders.  This makes it
    so duplicate responses from the same sender are ignored.
    
    Fixes [Bug #12838]


diff --git a/lib/resolv.rb b/lib/resolv.rb
index d78531e174..d50940ad15 100644
--- a/lib/resolv.rb
+++ b/lib/resolv.rb
@@ -706,7 +706,7 @@ def request(sender, tout)
       end
 
       def sender_for(addr, msg)
-        @senders[[addr,msg.id]]
+        @senders.delete([addr,msg.id])
       end
 
       def close
[snip]
```

----------------------------------------
Bug #17658: DNS resolution failure with multiple named resolvers
https://bugs.ruby-lang.org/issues/17658#change-90603

* Author: mcarpenter (Martin Carpenter)
* Status: Open
* Priority: Normal
* ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
* Backport: 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN, 3.0: UNKNOWN
----------------------------------------
## Description

I created a `Resolv::DNS` resolver with two nameservers described using their domain names. Calling `#getresources` on this for an `A` or `NS` (and possibly other resource types) of domain `example.com` returns an empty list (no results, no error). I expected it to return the corresponding resource record (IP of `example.com`).

Instead if the `Resolv::DNS` instance is created with one resolver domain name or two resolvers' IP addresses then correct results are obtained. The error occurs only when more than two nameservers [or possibly more] are specified using their domain names.

## Testcases

I used two well-known public DNS servers to test (they have funky but legitimate TLDs):
 * dns.google (8.8.4.4, 8.8.8.8)
 * one.one.one.one (1.1.1.1, 1.0.0.1)

### ✗ Failing: two nameservers by name
```ruby
require 'resolv'
Resolv::DNS.new({nameserver: ['dns.google', 'one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> []
```

### ✓ Successful: one nameserver by name
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: 'dns.google'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95df9ad8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=16840>]
Resolv::DNS.new({nameserver: ['one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95517c80 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=77160>]
```

### ✓ Successful: one nameserver by IP
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e28d38 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20931>]
Resolv::DNS.new({nameserver: '1.1.1.1'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e41360 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=66081>]
```

### ✓ Successful: two nameservers by IP
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4', '1.1.1.1']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95d62ea8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20894>]
```

## A little analysis

I didn't get to the bottom of this but this may help:
 * When only one nameserver is used then a `Resolv::DNS::Requester::ConnectedUDP::Sender` is used; when two nameservers are used an `UnconnectedUDP::Sender` is used.
 * The code appears to be timing out and then retried even though correct requests are made and responses received.
 * In particular, if I packet trace 53/udp then the conversation is exactly as I would expect and near identical in both failing and successful cases. That is:
   * Request A record for first nameserver from local resolver
   * Receive IP of first nameserver
   * Request A record of `example.com` from first nameserver
   * Receive IP of `example.com`
   In the successful case, the conversation ends here. In the failing case, the code round-robins between the two nameservers until it finally returns `[]`.


## Test environment

Tested ruby 2.5.0p0 on Red Hat 6 and rubies 2.7.1p83, 2.7.2p137 on Ubuntu 20 from two different networks with identical results.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [ruby-core:102937] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers
  2021-02-26  9:32 [ruby-core:102614] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers mcarpenter
  2021-02-26  9:38 ` [ruby-core:102615] " mcarpenter
  2021-02-26 10:04 ` [ruby-core:102616] " mcarpenter
@ 2021-03-20  4:19 ` nagachika00
  2021-04-04 23:48 ` [ruby-core:103225] " usa
  2021-04-07 22:58 ` [ruby-core:103282] " sam.saffron
  4 siblings, 0 replies; 6+ messages in thread
From: nagachika00 @ 2021-03-20  4:19 UTC (permalink / raw)
  To: ruby-core

Issue #17658 has been updated by nagachika (Tomoyuki Chikanaga).

Backport changed from 2.6: REQUIRED, 2.7: REQUIRED, 3.0: DONTNEED to 2.6: REQUIRED, 2.7: DONE, 3.0: DONTNEED

ruby_2_7 70c3a195f39763dccdf9367d0c9b7e815431a41a merged revision(s) 9682db065158da5fa4ec8a3bc267da45b429b92c.

----------------------------------------
Bug #17658: DNS resolution failure with multiple named resolvers
https://bugs.ruby-lang.org/issues/17658#change-91003

* Author: mcarpenter (Martin Carpenter)
* Status: Closed
* Priority: Normal
* ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
* Backport: 2.6: REQUIRED, 2.7: DONE, 3.0: DONTNEED
----------------------------------------
## Description

I created a `Resolv::DNS` resolver with two nameservers described using their domain names. Calling `#getresources` on this for an `A` or `NS` (and possibly other resource types) of domain `example.com` returns an empty list (no results, no error). I expected it to return the corresponding resource record (IP of `example.com`).

Instead if the `Resolv::DNS` instance is created with one resolver domain name or two resolvers' IP addresses then correct results are obtained. The error occurs only when more than two nameservers [or possibly more] are specified using their domain names.

## Testcases

I used two well-known public DNS servers to test (they have funky but legitimate TLDs):
 * dns.google (8.8.4.4, 8.8.8.8)
 * one.one.one.one (1.1.1.1, 1.0.0.1)

### ✗ Failing: two nameservers by name
```ruby
require 'resolv'
Resolv::DNS.new({nameserver: ['dns.google', 'one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> []
```

### ✓ Successful: one nameserver by name
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: 'dns.google'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95df9ad8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=16840>]
Resolv::DNS.new({nameserver: ['one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95517c80 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=77160>]
```

### ✓ Successful: one nameserver by IP
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e28d38 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20931>]
Resolv::DNS.new({nameserver: '1.1.1.1'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e41360 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=66081>]
```

### ✓ Successful: two nameservers by IP
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4', '1.1.1.1']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95d62ea8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20894>]
```

## A little analysis

I didn't get to the bottom of this but this may help:
 * When only one nameserver is used then a `Resolv::DNS::Requester::ConnectedUDP::Sender` is used; when two nameservers are used an `UnconnectedUDP::Sender` is used.
 * The code appears to be timing out and then retried even though correct requests are made and responses received.
 * In particular, if I packet trace 53/udp then the conversation is exactly as I would expect and near identical in both failing and successful cases. That is:
   * Request A record for first nameserver from local resolver
   * Receive IP of first nameserver
   * Request A record of `example.com` from first nameserver
   * Receive IP of `example.com`
   In the successful case, the conversation ends here. In the failing case, the code round-robins between the two nameservers until it finally returns `[]`.


## Test environment

Tested ruby 2.5.0p0 on Red Hat 6 and rubies 2.7.1p83, 2.7.2p137 on Ubuntu 20 from two different networks with identical results.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:103225] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers
  2021-02-26  9:32 [ruby-core:102614] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers mcarpenter
                   ` (2 preceding siblings ...)
  2021-03-20  4:19 ` [ruby-core:102937] " nagachika00
@ 2021-04-04 23:48 ` usa
  2021-04-07 22:58 ` [ruby-core:103282] " sam.saffron
  4 siblings, 0 replies; 6+ messages in thread
From: usa @ 2021-04-04 23:48 UTC (permalink / raw)
  To: ruby-core

Issue #17658 has been updated by usa (Usaku NAKAMURA).

Backport changed from 2.6: REQUIRED, 2.7: DONE, 3.0: DONTNEED to 2.6: DONE, 2.7: DONE, 3.0: DONTNEED

ruby_2_6 r67929 merged revision(s) 9682db065158da5fa4ec8a3bc267da45b429b92c.

----------------------------------------
Bug #17658: DNS resolution failure with multiple named resolvers
https://bugs.ruby-lang.org/issues/17658#change-91303

* Author: mcarpenter (Martin Carpenter)
* Status: Closed
* Priority: Normal
* ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
* Backport: 2.6: DONE, 2.7: DONE, 3.0: DONTNEED
----------------------------------------
## Description

I created a `Resolv::DNS` resolver with two nameservers described using their domain names. Calling `#getresources` on this for an `A` or `NS` (and possibly other resource types) of domain `example.com` returns an empty list (no results, no error). I expected it to return the corresponding resource record (IP of `example.com`).

Instead if the `Resolv::DNS` instance is created with one resolver domain name or two resolvers' IP addresses then correct results are obtained. The error occurs only when more than two nameservers [or possibly more] are specified using their domain names.

## Testcases

I used two well-known public DNS servers to test (they have funky but legitimate TLDs):
 * dns.google (8.8.4.4, 8.8.8.8)
 * one.one.one.one (1.1.1.1, 1.0.0.1)

### ✗ Failing: two nameservers by name
```ruby
require 'resolv'
Resolv::DNS.new({nameserver: ['dns.google', 'one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> []
```

### ✓ Successful: one nameserver by name
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: 'dns.google'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95df9ad8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=16840>]
Resolv::DNS.new({nameserver: ['one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95517c80 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=77160>]
```

### ✓ Successful: one nameserver by IP
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e28d38 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20931>]
Resolv::DNS.new({nameserver: '1.1.1.1'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e41360 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=66081>]
```

### ✓ Successful: two nameservers by IP
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4', '1.1.1.1']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95d62ea8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20894>]
```

## A little analysis

I didn't get to the bottom of this but this may help:
 * When only one nameserver is used then a `Resolv::DNS::Requester::ConnectedUDP::Sender` is used; when two nameservers are used an `UnconnectedUDP::Sender` is used.
 * The code appears to be timing out and then retried even though correct requests are made and responses received.
 * In particular, if I packet trace 53/udp then the conversation is exactly as I would expect and near identical in both failing and successful cases. That is:
   * Request A record for first nameserver from local resolver
   * Receive IP of first nameserver
   * Request A record of `example.com` from first nameserver
   * Receive IP of `example.com`
   In the successful case, the conversation ends here. In the failing case, the code round-robins between the two nameservers until it finally returns `[]`.


## Test environment

Tested ruby 2.5.0p0 on Red Hat 6 and rubies 2.7.1p83, 2.7.2p137 on Ubuntu 20 from two different networks with identical results.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:103282] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers
  2021-02-26  9:32 [ruby-core:102614] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers mcarpenter
                   ` (3 preceding siblings ...)
  2021-04-04 23:48 ` [ruby-core:103225] " usa
@ 2021-04-07 22:58 ` sam.saffron
  4 siblings, 0 replies; 6+ messages in thread
From: sam.saffron @ 2021-04-07 22:58 UTC (permalink / raw)
  To: ruby-core

Issue #17658 has been updated by sam.saffron (Sam Saffron).


This has caused a pretty giant regression: 

https://bugs.ruby-lang.org/issues/17781

Requests are now being never cleaned up cause sender_for as a side effect causes a bypass on cleanup. 

----------------------------------------
Bug #17658: DNS resolution failure with multiple named resolvers
https://bugs.ruby-lang.org/issues/17658#change-91366

* Author: mcarpenter (Martin Carpenter)
* Status: Closed
* Priority: Normal
* ruby -v: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-linux]
* Backport: 2.6: DONE, 2.7: DONE, 3.0: DONTNEED
----------------------------------------
## Description

I created a `Resolv::DNS` resolver with two nameservers described using their domain names. Calling `#getresources` on this for an `A` or `NS` (and possibly other resource types) of domain `example.com` returns an empty list (no results, no error). I expected it to return the corresponding resource record (IP of `example.com`).

Instead if the `Resolv::DNS` instance is created with one resolver domain name or two resolvers' IP addresses then correct results are obtained. The error occurs only when more than two nameservers [or possibly more] are specified using their domain names.

## Testcases

I used two well-known public DNS servers to test (they have funky but legitimate TLDs):
 * dns.google (8.8.4.4, 8.8.8.8)
 * one.one.one.one (1.1.1.1, 1.0.0.1)

### ✗ Failing: two nameservers by name
```ruby
require 'resolv'
Resolv::DNS.new({nameserver: ['dns.google', 'one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> []
```

### ✓ Successful: one nameserver by name
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: 'dns.google'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95df9ad8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=16840>]
Resolv::DNS.new({nameserver: ['one.one.one.one']}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95517c80 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=77160>]
```

### ✓ Successful: one nameserver by IP
(either as a single-item list or a string)
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e28d38 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20931>]
Resolv::DNS.new({nameserver: '1.1.1.1'}).getresources('example.com', Resolv::DNS::Resource::IN::A)
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95e41360 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=66081>]
```

### ✓ Successful: two nameservers by IP
```ruby
Resolv::DNS.new({nameserver: ['8.8.4.4', '1.1.1.1']}).getresources('example.com', Resolv::DNS::Resource::IN::A) 
=> [#<Resolv::DNS::Resource::IN::A:0x000055ee95d62ea8 @address=#<Resolv::IPv4 93.184.216.34>, @ttl=20894>]
```

## A little analysis

I didn't get to the bottom of this but this may help:
 * When only one nameserver is used then a `Resolv::DNS::Requester::ConnectedUDP::Sender` is used; when two nameservers are used an `UnconnectedUDP::Sender` is used.
 * The code appears to be timing out and then retried even though correct requests are made and responses received.
 * In particular, if I packet trace 53/udp then the conversation is exactly as I would expect and near identical in both failing and successful cases. That is:
   * Request A record for first nameserver from local resolver
   * Receive IP of first nameserver
   * Request A record of `example.com` from first nameserver
   * Receive IP of `example.com`
   In the successful case, the conversation ends here. In the failing case, the code round-robins between the two nameservers until it finally returns `[]`.


## Test environment

Tested ruby 2.5.0p0 on Red Hat 6 and rubies 2.7.1p83, 2.7.2p137 on Ubuntu 20 from two different networks with identical results.



-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2021-04-07 22:58 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-02-26  9:32 [ruby-core:102614] [Ruby master Bug#17658] DNS resolution failure with multiple named resolvers mcarpenter
2021-02-26  9:38 ` [ruby-core:102615] " mcarpenter
2021-02-26 10:04 ` [ruby-core:102616] " mcarpenter
2021-03-20  4:19 ` [ruby-core:102937] " nagachika00
2021-04-04 23:48 ` [ruby-core:103225] " usa
2021-04-07 22:58 ` [ruby-core:103282] " sam.saffron

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).