nodejs / node

Node.js JavaScript runtime ✨🐢🚀✨
https://nodejs.org
Other
106.54k stars 29.04k forks source link

dns.resolve*() Fails when Responses Exceed 512 Bytes #40076

Closed derekrprice closed 1 year ago

derekrprice commented 3 years ago

Version

v14.17.6

Platform

Linux drp-node-tests 5.4.0-1058-azure #60~18.04.1-Ubuntu SMP Tue Aug 31 20:34:46 UTC 2021 x86_64 GNU/Linux

Subsystem

dns

What steps will reproduce the bug?

const { Resolver } = require('dns');
const dns = new Resolver();
dns.resolveTxt(process.argv[2], (err, res) => {
    if (err) {
        console.log(err);
    } else {
        console.log(res);
    }
});

How often does it reproduce? Is there a required condition?

This will fail for any query that returns over 512 bytes.

What is the expected behavior?

This should return data for result sizes up to 4096 bytes. You can see that dig is fine, returning 715 bytes with the same query:

$ dig TXT google.com

; <<>> DiG 9.10.3-P4-Debian <<>> TXT google.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32543
;; flags: qr rd ra; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;google.com.                    IN      TXT

;; ANSWER SECTION:
google.com.             30      IN      TXT     "google-site-verification=TV9-DBe4R80X4v0M4U_bd_J9cpOJM0nikft0jAgjmsQ"
google.com.             30      IN      TXT     "v=spf1 include:_spf.google.com ~all"
google.com.             30      IN      TXT     "docusign=1b0a6754-49b1-4db5-8540-d2c12664b289"
google.com.             30      IN      TXT     "globalsign-smime-dv=CDYX+XFHUw2wml6/Gb8+59BsH31KzUr6c1l2BPvqKX8="
google.com.             30      IN      TXT     "google-site-verification=wD8N7i1JTNTkezJ49swvWW48f8_9xveREV4oB-0Hf5o"
google.com.             30      IN      TXT     "facebook-domain-verification=22rm551cu4k0ab0bxsw536tlds4h95"
google.com.             30      IN      TXT     "docusign=05958488-4752-4ef2-95eb-aa7ba8a3bd0e"
google.com.             30      IN      TXT     "apple-domain-verification=30afIBcvSuDV2PLX"
google.com.             30      IN      TXT     "MS=E4A68B9AB2BB9670BCE15412F62916164C0B20BB"

;; Query time: 4 msec
;; SERVER: 10.0.0.10#53(10.0.0.10)
;; WHEN: Fri Sep 10 21:02:16 UTC 2021
;; MSG SIZE  rcvd: 715

For result sets smaller than 512 bytes, both node and dig agree:

$ node dns-test2.js  partechgss.com
[
  [ 'ryb3spm2r33rtxl189nqs5n41xxrzmlz' ],
  [ 'v=spf1 include:_spf.google.com ~all' ],
  [ 'MS=ms32721923' ],
  [ 'MS=ms56152555' ]
]
$ dig TXT partechgss.com

; <<>> DiG 9.10.3-P4-Debian <<>> TXT partechgss.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56392
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;partechgss.com.                        IN      TXT

;; ANSWER SECTION:
partechgss.com.         30      IN      TXT     "MS=ms56152555"
partechgss.com.         30      IN      TXT     "MS=ms32721923"
partechgss.com.         30      IN      TXT     "v=spf1 include:_spf.google.com ~all"
partechgss.com.         30      IN      TXT     "ryb3spm2r33rtxl189nqs5n41xxrzmlz"

;; Query time: 14 msec
;; SERVER: 10.0.0.10#53(10.0.0.10)
;; WHEN: Fri Sep 10 21:15:21 UTC 2021
;; MSG SIZE  rcvd: 244

What do you see instead?

ESERVFAIL error from the DNS server.

$ node dns-test2.js google.com
Error: queryTxt ESERVFAIL google.com
    at QueryReqWrap.onresolve [as oncomplete] (dns.js:206:19) {
  errno: undefined,
  code: 'ESERVFAIL',
  syscall: 'queryTxt',
  hostname: 'google.com'
}

Additional information

Running tcpdump, I see that the node query does not include the EDNS UDPsize=4096 option:

TXT? google.com. (28)

Whereas the dig request does:

TXT? google.com. ar: . OPT UDPsize=4096 (39)

If dns.resolve() were to include the same EDNS option with queries, this would probably work fine.

bnoordhuis commented 1 year ago

v14.x is EOL now and I can't reproduce with newer node versions so I believe this has been fixed.