From b0c48d8e45c8d92e3bd55b35f58c18f8e4b4fbea Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 22 Sep 2008 20:06:25 +0000 Subject: [PATCH] Oops; we need to make sure that DNS request names are matched in the _questions_ section of the replies. Rejecting answers whether the _answers_ section did not match made us reject A records waiting at the end of a CNAME record. Bug 823. svn:r16933 --- ChangeLog | 3 +++ src/or/eventdns.c | 43 ++++++++++++++++++++----------------------- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index a5c9c47bcc..fe21be1f76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -12,6 +12,9 @@ Changes in version 0.2.1.6-alpha - 2008-09-xx descriptor from a hidden service directory for which the router descriptor has not yet been downloaded. Fixes bug 767. Bugfix on 0.2.0.10-alpha. + - DNS replies need to have names matching their requests, but these names + should be in the questions section, not necessarily in the answers + section. Fixes bug 823. Bugfix on 0.2.1.5-alpha. o Minor bugfixes: - Fix compile on OpenBSD 4.4-current. Bugfix on 0.2.1.5-alpha. diff --git a/src/or/eventdns.c b/src/or/eventdns.c index ba0f7a7d11..fd8297e56f 100644 --- a/src/or/eventdns.c +++ b/src/or/eventdns.c @@ -873,6 +873,7 @@ reply_parse(u8 *packet, int length) { struct reply reply; struct request *req = NULL; unsigned int i; + int name_matches = 0; GET16(trans_id); GET16(flags); @@ -913,16 +914,20 @@ reply_parse(u8 *packet, int length) { */ GET_NAME; j += 4; + if (!strcasecmp(req->name, tmp_name)) + name_matches = 1; if (j >= length) goto err; } + if (!name_matches) + goto err; + /* now we have the answer section which looks like * */ for (i = 0; i < answers; ++i) { u16 type, class; - int name_matches; GET_NAME; GET16(type); @@ -930,8 +935,6 @@ reply_parse(u8 *packet, int length) { GET32(ttl); GET16(datalength); - name_matches = !strcasecmp(req->name, tmp_name); - if (type == TYPE_A && class == CLASS_INET) { int addrcount, addrtocopy; if (req->request_type != TYPE_A) { @@ -945,25 +948,21 @@ reply_parse(u8 *packet, int length) { ttl_r = MIN(ttl_r, ttl); /* we only bother with the first four addresses. */ if (j + 4*addrtocopy > length) goto err; - if (name_matches) { - memcpy(&reply.data.a.addresses[reply.data.a.addrcount], - packet + j, 4*addrtocopy); - reply.data.a.addrcount += addrtocopy; - reply.have_answer = 1; - if (reply.data.a.addrcount == MAX_ADDRS) break; - } + memcpy(&reply.data.a.addresses[reply.data.a.addrcount], + packet + j, 4*addrtocopy); + reply.data.a.addrcount += addrtocopy; + reply.have_answer = 1; + if (reply.data.a.addrcount == MAX_ADDRS) break; j += 4*addrtocopy; } else if (type == TYPE_PTR && class == CLASS_INET) { if (req->request_type != TYPE_PTR) { j += datalength; continue; } GET_NAME; - if (name_matches) { - strlcpy(reply.data.ptr.name, tmp_name, - sizeof(reply.data.ptr.name)); - ttl_r = MIN(ttl_r, ttl); - reply.have_answer = 1; - } + strlcpy(reply.data.ptr.name, tmp_name, + sizeof(reply.data.ptr.name)); + ttl_r = MIN(ttl_r, ttl); + reply.have_answer = 1; break; } else if (type == TYPE_AAAA && class == CLASS_INET) { int addrcount, addrtocopy; @@ -978,13 +977,11 @@ reply_parse(u8 *packet, int length) { /* we only bother with the first four addresses. */ if (j + 16*addrtocopy > length) goto err; - if (name_matches) { - memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount], - packet + j, 16*addrtocopy); - reply.data.aaaa.addrcount += addrtocopy; - reply.have_answer = 1; - if (reply.data.aaaa.addrcount == MAX_ADDRS) break; - } + memcpy(&reply.data.aaaa.addresses[reply.data.aaaa.addrcount], + packet + j, 16*addrtocopy); + reply.data.aaaa.addrcount += addrtocopy; + reply.have_answer = 1; + if (reply.data.aaaa.addrcount == MAX_ADDRS) break; j += 16*addrtocopy; } else { /* skip over any other type of resource */ -- 2.11.4.GIT