Bug #3835: Resolv::DNS: Retry via TCP on truncated UDP response
http://redmine.ruby-lang.org/issues/show/3835

Author: Julian Mehnle
Status: Open, Priority: Normal
Category: lib
ruby -v: ruby 1.9.2p0 (2010-08-18 revision 29036) [x86_64-linux]

Resolv::DNS has code implementing DNS queries via TCP, but it is not curr=
ently used at all.  Furthermore, any truncated responses received via UDP=
 are parsed and intact RRs are used, silently discarding any truncated RR=
s.  E.g.:

    $ dig amazon.com TXT
    ;; Truncated, retrying in TCP mode.

    ; <<>> DiG 9.6.1-P3 <<>> amazon.com TXT
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 1197
    ;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0

    ;; QUESTION SECTION:
    ;amazon.com.                    IN      TXT

    ;; ANSWER SECTION:
    amazon.com.             3592    IN      TXT     "spf2.0/pra ip4:207.1=
71.160.0/19 ip4:87.238.80.0/21 ip4:72.21.193.0/24
                                                    ip4:72.21.196.0/22 ip=
4:72.21.208.0/24 ip4:72.21.205.0/24
                                                    ip4:72.21.209.0/24 ip=
4:194.154.193.200/28 ip4:194.7.41.152/28
                                                    ip4:212.123.28.40/32 =
ip4:203.81.17.0/24 ~all"
    amazon.com.             3592    IN      TXT     "v=3Dspf1 ip4:207.171=
.160.0/19 ip4:87.238.80.0/21 ip4:72.21.193.0/24
                                                    ip4:72.21.196.0/22 ip=
4:72.21.208.0/24 ip4:72.21.205.0/24
                                                    ip4:72.21.209.0/24 ip=
4:194.154.193.200/28 ip4:194.7.41.152/28
                                                    ip4:212.123.28.40/32 =
ip4:203.81.17.0/24 ~all"

    ;; Query time: 0 msec
    ;; SERVER: 127.0.0.1#53(127.0.0.1)
    ;; WHEN: Wed Sep 15 20:21:49 2010
    ;; MSG SIZE  rcvd: 516

With an unpatched 1.9.2 Resolv::DNS:

    >> pp Resolv::DNS.new.getresources('amazon.com', Resolv::DNS::Resourc=
e::IN::TXT); nil
    [#<Resolv::DNS::Resource::IN::TXT:0x0000000143b0b0
      @strings=3D
       ["spf2.0/pra ip4:207.171.160.0/19 ip4:87.238.80.0/21 ip4:72.21.193=
.0/24 ip4:72.21.196.0/22
        ip4:72.21.208.0/24 ip4:72.21.205.0/24 ip4:72.21.209.0/24 ip4:194.=
154.193.200/28 ip4:194.7.41.152/28
        ip4:212.123.28.40/32 ip4:203.81.17.0/24 ~all"],
      @ttl=3D2185>]
    =3D> nil

The attached patch changes Resolv::DNS#each_resource to check UDP respons=
es for truncation and retries via TCP, which is the proper behavior per R=
FC 1123, section 6.1.3.2 <http://tools.ietf.org/html/rfc1123#page-75> and=
 implemented by most resolver libraries.

Effect:

    >> pp Resolv::DNS.new.getresources('amazon.com', Resolv::DNS::Resourc=
e::IN::TXT); nil
    [#<Resolv::DNS::Resource::IN::TXT:0x0000000214adf0
      @strings=3D
       ["spf2.0/pra ip4:207.171.160.0/19 ip4:87.238.80.0/21 ip4:72.21.193=
.0/24 ip4:72.21.196.0/22
        ip4:72.21.208.0/24 ip4:72.21.205.0/24 ip4:72.21.209.0/24 ip4:194.=
154.193.200/28 ip4:194.7.41.152/28
        ip4:212.123.28.40/32 ip4:203.81.17.0/24 ~all"],
      @ttl=3D2237>,
     #<Resolv::DNS::Resource::IN::TXT:0x0000000214a580
      @strings=3D
       ["v=3Dspf1 ip4:207.171.160.0/19 ip4:87.238.80.0/21 ip4:72.21.193.0=
/24 ip4:72.21.196.0/22
        ip4:72.21.208.0/24 ip4:72.21.205.0/24 ip4:72.21.209.0/24 ip4:194.=
154.193.200/28 ip4:194.7.41.152/28
        ip4:212.123.28.40/32 ip4:203.81.17.0/24 ~all"],
      @ttl=3D2237>]
    =3D> nil

I'm also attaching a patch for 1.8.7 in the hope that it will be merged i=
nto 1.8.7, too.

Of course it would be nice to also support EDNS0, but that's beyond what =
I can deliver right now.


----------------------------------------
http://redmine.ruby-lang.org
LS0tIC91c3IvbGliL3J1YnkvMS45LjIvcmVzb2x2LnJiCTIwMTAtMDktMTIg
MTQ6NDc6NDcuMDAwMDAwMDAwICswMDAwCisrKyByZXNvbHYtMS45LjIucmIJ
MjAxMC0wOS0xNSAyMDo0MjoxOS4wMzU1MjMxMjMgKzAwMDAKQEAgLTQ5Miw3
ICs0OTIsNyBAQAogCiAgICAgZGVmIGVhY2hfcmVzb3VyY2UobmFtZSwgdHlw
ZWNsYXNzLCAmcHJvYykKICAgICAgIGxhenlfaW5pdGlhbGl6ZQotICAgICAg
cmVxdWVzdGVyID0gbWFrZV9yZXF1ZXN0ZXIKKyAgICAgIHJlcXVlc3RlciA9
IG1ha2VfdWRwX3JlcXVlc3RlcgogICAgICAgc2VuZGVycyA9IHt9CiAgICAg
ICBiZWdpbgogICAgICAgICBAY29uZmlnLnJlc29sdihuYW1lKSB7fGNhbmRp
ZGF0ZSwgdG91dCwgbmFtZXNlcnZlciwgcG9ydHwKQEAgLTUwNiw3ICs1MDYs
MTggQEAKICAgICAgICAgICByZXBseSwgcmVwbHlfbmFtZSA9IHJlcXVlc3Rl
ci5yZXF1ZXN0KHNlbmRlciwgdG91dCkKICAgICAgICAgICBjYXNlIHJlcGx5
LnJjb2RlCiAgICAgICAgICAgd2hlbiBSQ29kZTo6Tm9FcnJvcgotICAgICAg
ICAgICAgZXh0cmFjdF9yZXNvdXJjZXMocmVwbHksIHJlcGx5X25hbWUsIHR5
cGVjbGFzcywgJnByb2MpCisgICAgICAgICAgICBpZiByZXBseS50YyBhbmQg
bm90IFJlcXVlc3Rlcjo6VENQID09PSByZXF1ZXN0ZXIKKyAgICAgICAgICAg
ICAgIyBSZXRyeSB2aWEgVENQOgorICAgICAgICAgICAgICByZXF1ZXN0ZXIg
PSBtYWtlX3RjcF9yZXF1ZXN0ZXIKKyAgICAgICAgICAgICAgc2VuZGVycyA9
IHt9CisgICAgICAgICAgICAgICMgVGhpcyB3aWxsIHVzZSBUQ1AgZm9yIGFs
bCByZW1haW5pbmcgY2FuZGlkYXRlcyAoYXNzdW1pbmcgdGhlCisgICAgICAg
ICAgICAgICMgY3VycmVudCBjYW5kaWRhdGUgZG9lcyBub3QgYWxyZWFkeSBy
ZXNwb25kIHN1Y2Nlc3NmdWxseSB2aWEKKyAgICAgICAgICAgICAgIyBUQ1Ap
LiAgVGhpcyBtYWtlcyBzZW5zZSBiZWNhdXNlIHdlIGFscmVhZHkga25vdyB0
aGUgZnVsbAorICAgICAgICAgICAgICAjIHJlc3BvbnNlIHdpbGwgbm90IGZp
dCBpbiBhbiB1bnRydW5jYXRlZCBVRFAgcGFja2V0LgorICAgICAgICAgICAg
ICByZWRvCisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgIGV4dHJh
Y3RfcmVzb3VyY2VzKHJlcGx5LCByZXBseV9uYW1lLCB0eXBlY2xhc3MsICZw
cm9jKQorICAgICAgICAgICAgZW5kCiAgICAgICAgICAgICByZXR1cm4KICAg
ICAgICAgICB3aGVuIFJDb2RlOjpOWERvbWFpbgogICAgICAgICAgICAgcmFp
c2UgQ29uZmlnOjpOWERvbWFpbi5uZXcocmVwbHlfbmFtZS50b19zKQpAQCAt
NTE5LDcgKzUzMCw3IEBACiAgICAgICBlbmQKICAgICBlbmQKIAotICAgIGRl
ZiBtYWtlX3JlcXVlc3RlciAjIDpub2RvYzoKKyAgICBkZWYgbWFrZV91ZHBf
cmVxdWVzdGVyICMgOm5vZG9jOgogICAgICAgbmFtZXNlcnZlcl9wb3J0ID0g
QGNvbmZpZy5uYW1lc2VydmVyX3BvcnQKICAgICAgIGlmIG5hbWVzZXJ2ZXJf
cG9ydC5sZW5ndGggPT0gMQogICAgICAgICBSZXF1ZXN0ZXI6OkNvbm5lY3Rl
ZFVEUC5uZXcoKm5hbWVzZXJ2ZXJfcG9ydFswXSkKQEAgLTUyOCw2ICs1Mzks
MTEgQEAKICAgICAgIGVuZAogICAgIGVuZAogCisgICAgZGVmIG1ha2VfdGNw
X3JlcXVlc3RlciAjIDpub2RvYzoKKyAgICAgIG5hbWVzZXJ2ZXJfcG9ydCA9
IEBjb25maWcubmFtZXNlcnZlcl9wb3J0CisgICAgICByZXR1cm4gUmVxdWVz
dGVyOjpUQ1AubmV3KCpuYW1lc2VydmVyX3BvcnRbMF0pCisgICAgZW5kCisK
ICAgICBkZWYgZXh0cmFjdF9yZXNvdXJjZXMobXNnLCBuYW1lLCB0eXBlY2xh
c3MpICMgOm5vZG9jOgogICAgICAgaWYgdHlwZWNsYXNzIDwgUmVzb3VyY2U6
OkFOWQogICAgICAgICBuMCA9IE5hbWUuY3JlYXRlKG5hbWUpCg==
LS0tIC91c3IvbGliL3J1YnkvMS44L3Jlc29sdi5yYgkyMDEwLTA1LTIyIDEz
OjMxOjUyLjAwMDAwMDAwMCArMDAwMAorKysgcmVzb2x2LTEuOC43LnJiCTIw
MTAtMDktMTUgMjA6Mzk6NDEuNTU1NDQ1MzQ1ICswMDAwCkBAIC00NzUsNyAr
NDc1LDcgQEAKICAgCiAgICAgZGVmIGVhY2hfcmVzb3VyY2UobmFtZSwgdHlw
ZWNsYXNzLCAmcHJvYykKICAgICAgIGxhenlfaW5pdGlhbGl6ZQotICAgICAg
cmVxdWVzdGVyID0gbWFrZV9yZXF1ZXN0ZXIKKyAgICAgIHJlcXVlc3RlciA9
IG1ha2VfdWRwX3JlcXVlc3RlcgogICAgICAgc2VuZGVycyA9IHt9CiAgICAg
ICBiZWdpbgogICAgICAgICBAY29uZmlnLnJlc29sdihuYW1lKSB7fGNhbmRp
ZGF0ZSwgdG91dCwgbmFtZXNlcnZlcnwKQEAgLTQ4OSw3ICs0ODksMTggQEAK
ICAgICAgICAgICByZXBseSwgcmVwbHlfbmFtZSA9IHJlcXVlc3Rlci5yZXF1
ZXN0KHNlbmRlciwgdG91dCkKICAgICAgICAgICBjYXNlIHJlcGx5LnJjb2Rl
CiAgICAgICAgICAgd2hlbiBSQ29kZTo6Tm9FcnJvcgotICAgICAgICAgICAg
ZXh0cmFjdF9yZXNvdXJjZXMocmVwbHksIHJlcGx5X25hbWUsIHR5cGVjbGFz
cywgJnByb2MpCisgICAgICAgICAgICBpZiByZXBseS50YyBhbmQgbm90IFJl
cXVlc3Rlcjo6VENQID09PSByZXF1ZXN0ZXIKKyAgICAgICAgICAgICAgIyBS
ZXRyeSB2aWEgVENQOgorICAgICAgICAgICAgICByZXF1ZXN0ZXIgPSBtYWtl
X3RjcF9yZXF1ZXN0ZXIKKyAgICAgICAgICAgICAgc2VuZGVycyA9IHt9Cisg
ICAgICAgICAgICAgICMgVGhpcyB3aWxsIHVzZSBUQ1AgZm9yIGFsbCByZW1h
aW5pbmcgY2FuZGlkYXRlcyAoYXNzdW1pbmcgdGhlCisgICAgICAgICAgICAg
ICMgY3VycmVudCBjYW5kaWRhdGUgZG9lcyBub3QgYWxyZWFkeSByZXNwb25k
IHN1Y2Nlc3NmdWxseSB2aWEKKyAgICAgICAgICAgICAgIyBUQ1ApLiAgVGhp
cyBtYWtlcyBzZW5zZSBiZWNhdXNlIHdlIGFscmVhZHkga25vdyB0aGUgZnVs
bAorICAgICAgICAgICAgICAjIHJlc3BvbnNlIHdpbGwgbm90IGZpdCBpbiBh
biB1bnRydW5jYXRlZCBVRFAgcGFja2V0LgorICAgICAgICAgICAgICByZWRv
CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgIGV4dHJhY3RfcmVz
b3VyY2VzKHJlcGx5LCByZXBseV9uYW1lLCB0eXBlY2xhc3MsICZwcm9jKQor
ICAgICAgICAgICAgZW5kCiAgICAgICAgICAgICByZXR1cm4KICAgICAgICAg
ICB3aGVuIFJDb2RlOjpOWERvbWFpbgogICAgICAgICAgICAgcmFpc2UgQ29u
ZmlnOjpOWERvbWFpbi5uZXcocmVwbHlfbmFtZS50b19zKQpAQCAtNTAyLDcg
KzUxMyw3IEBACiAgICAgICBlbmQKICAgICBlbmQKIAotICAgIGRlZiBtYWtl
X3JlcXVlc3RlciAjIDpub2RvYzoKKyAgICBkZWYgbWFrZV91ZHBfcmVxdWVz
dGVyICMgOm5vZG9jOgogICAgICAgbmFtZXNlcnZlcl9wb3J0ID0gQGNvbmZp
Zy5uYW1lc2VydmVyX3BvcnQKICAgICAgIGlmIG5hbWVzZXJ2ZXJfcG9ydC5s
ZW5ndGggPT0gMQogICAgICAgICBSZXF1ZXN0ZXI6OkNvbm5lY3RlZFVEUC5u
ZXcoKm5hbWVzZXJ2ZXJfcG9ydFswXSkKQEAgLTUxMSw2ICs1MjIsMTEgQEAK
ICAgICAgIGVuZAogICAgIGVuZAogCisgICAgZGVmIG1ha2VfdGNwX3JlcXVl
c3RlciAjIDpub2RvYzoKKyAgICAgIG5hbWVzZXJ2ZXJfcG9ydCA9IEBjb25m
aWcubmFtZXNlcnZlcl9wb3J0CisgICAgICByZXR1cm4gUmVxdWVzdGVyOjpU
Q1AubmV3KCpuYW1lc2VydmVyX3BvcnRbMF0pCisgICAgZW5kCisKICAgICBk
ZWYgZXh0cmFjdF9yZXNvdXJjZXMobXNnLCBuYW1lLCB0eXBlY2xhc3MpICMg
Om5vZG9jOgogICAgICAgaWYgdHlwZWNsYXNzIDwgUmVzb3VyY2U6OkFOWQog
ICAgICAgICBuMCA9IE5hbWUuY3JlYXRlKG5hbWUpCg==