Bug #12838
closedDuplication of UDP packets for DNS responses causing "no address" results for valid hostnames
Description
A network that I'm running a Ruby app on has an issue where it is duplicating UDP packets (a separate issue that I need to fix). This is resulting in intermittent "not found" results for valid hostnames.
In my case, my resolver is setup to use multiple search domains, say bad1.com, bad2.com, and good.com. A lookup for hostname 'example' will perform lookups on example.bad1.com, example.bad2.com, example.good.com, and then finally plain 'example'. Say example.good.com is a valid hostname with a corresponding record. What I am seeing is that the duplication of the response s for the first two DNS queries are being read as the response for example.good.com, and I am getting a "no address for example.good.com" error message. Note that this is only happening every once in awhile, when the responses are duplicated.
I have been able to reproduce with the attached server.rb and client.rb files. I also noticed that if I changed the following line to:
https://github.com/ruby/ruby/blob/5827d8e887d881eb3a6e6ea7410590261c90545f/lib/resolv.rb#L709
if (s = sender_for(from, msg)) && s == sender
then my problems went away. I have to admit though, I don't really understand the entirely of that file. Not from lack of effort.
You should be able to reproduce the error by running server.rb and client.rb. You may need to use sudo for server.rb in order to bind to port 53 (or you can modify the files to use a higher port).
Files
Updated by jschneiderhan (Jon-Erik Schneiderhan) about 8 years ago
- File check-sender.diff check-sender.diff added
I added a diff file (check-sender.diff) instead of using the issue description to show the change I made to fix the error on my machine. The change and diff were made against the v2_3_1 tag in the git repo mirrored on github. I'm not necessarily suggesting it as the fix for the issue, just mentioning it as something interesting that I noticed.
Updated by jschneiderhan (Jon-Erik Schneiderhan) about 8 years ago
I looked through some of the DNS RFCs, at the suggestion of a colleague, to see if there was any mention of a standard way of dealing with duplicate responses. I didn't see anything specifically calling out duplicates, but I did find this section in the "Resolver Implementation" section of RFC 1035:
The next step is to match the response to a current resolver request. The recommended strategy is to do a preliminary matching using the ID field in the domain header, and then to verify that the question section corresponds to the information currently desired. This requires that the transmission algorithm devote several bits of the domain ID field to a request identifier of some sort.
I think the current problem is that the transaction ID in the response is not being matched up with the transaction ID in the request. "sender_for(from, msg)" is looking up the sender based on the ID in the response, but it is never checked to see if the ID matches the ID of the message sent earlier on in the "request" method.
Updated by jeremyevans0 (Jeremy Evans) about 4 years ago
- Status changed from Open to Assigned
- Assignee set to akr (Akira Tanaka)
This is still in issue in the master branch. The underlying problem is resolv does not remove the [sender, message_id]
pair once a response has been received. I have submitted a pull request to fix this issue: https://github.com/ruby/ruby/pull/3536
Updated by jeremyevans (Jeremy Evans) about 4 years ago
- Status changed from Assigned to Closed
Applied in changeset git|9682db065158da5fa4ec8a3bc267da45b429b92c.
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]
Updated by nagachika (Tomoyuki Chikanaga) over 3 years ago
- Backport changed from 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN to 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN, 2.7: DONE
ruby_2_7 70c3a195f39763dccdf9367d0c9b7e815431a41a merged revision(s) 9682db065158da5fa4ec8a3bc267da45b429b92c.