From: Niels Provos Date: Sat, 30 Aug 2008 23:19:49 +0000 (+0000) Subject: Match the query in DNS replies to the query in the request; from Vsevolod Stakhov X-Git-Tag: release-2.0.1-alpha~225 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a710d817ad67dccbf75526738d658b881126d6d1;p=libevent Match the query in DNS replies to the query in the request; from Vsevolod Stakhov svn:r930 --- diff --git a/ChangeLog b/ChangeLog index 900f0c69..aeb0882f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -122,6 +122,7 @@ Changes in current version: o Fix off-by-one errors in devpoll; from Ian Bell o Make event_add not change any state if it fails; reported by Ian Bell. o Fix a bug where headers arriving in multiple packets were not parsed; fix from Jiang Hong; test by me. + o Match the query in DNS replies to the query in the request; from Vsevolod Stakhov. Changes in 1.4.0: o allow \r or \n individually to separate HTTP headers instead of the standard "\r\n"; from Charles Kerr. diff --git a/evdns.c b/evdns.c index 8069e5d2..2325557c 100644 --- a/evdns.c +++ b/evdns.c @@ -711,7 +711,10 @@ reply_callback(struct evdns_request *const req, u32 ttl, u32 err, struct reply * static void reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply *reply) { int error; - static const int error_codes[] = {DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, DNS_ERR_NOTIMPL, DNS_ERR_REFUSED}; + static const int error_codes[] = { + DNS_ERR_FORMAT, DNS_ERR_SERVERFAILED, DNS_ERR_NOTEXIST, + DNS_ERR_NOTIMPL, DNS_ERR_REFUSED + }; if (flags & 0x020f || !reply || !reply->have_answer) { /* there was an error */ @@ -739,9 +742,10 @@ reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply * } break; case DNS_ERR_SERVERFAILED: - /* rcode 2 (servfailed) sometimes means "we are broken" and - * sometimes (with some binds) means "that request was very - * confusing." Treat this as a timeout, not a failure. + /* rcode 2 (servfailed) sometimes means "we + * are broken" and sometimes (with some binds) + * means "that request was very confusing." + * Treat this as a timeout, not a failure. */ log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; " "will allow the request to time out.", @@ -753,10 +757,13 @@ reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply * } if (req->search_state && req->request_type != TYPE_PTR) { - /* if we have a list of domains to search in, try the next one */ + /* if we have a list of domains to search in, + * try the next one */ if (!search_try_next(req)) { - /* a new request was issued so this request is finished and */ - /* the user callback will be made when that request (or a */ + /* a new request was issued so this + * request is finished and */ + /* the user callback will be made when + * that request (or a */ /* child of it) finishes. */ request_finished(req, &REQ_HEAD(req->base, req->trans_id)); return; @@ -833,10 +840,10 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) { /* parses a raw request from a nameserver */ static int reply_parse(struct evdns_base *base, u8 *packet, int length) { - int j = 0; /* index into packet */ + int j = 0, k = 0; /* index into packet */ u16 _t; /* used by the macros */ u32 _t32; /* used by the macros */ - char tmp_name[256]; /* used by the macros */ + char tmp_name[256], cmp_name[256]; /* used by the macros */ u16 trans_id, questions, answers, authority, additional, datalength; u16 flags = 0; @@ -870,10 +877,21 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) { /* This macro skips a name in the DNS reply. */ #define SKIP_NAME \ - do { tmp_name[0] = '\0'; \ - if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0) \ - goto err; \ - } while(0); + do { tmp_name[0] = '\0'; \ + if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\ + goto err; \ + } while(0) +#define TEST_NAME \ + do { tmp_name[0] = '\0'; \ + cmp_name[0] = '\0'; \ + k = j; \ + if (name_parse(packet, length, &j, tmp_name, sizeof(tmp_name))<0)\ + goto err; \ + if (name_parse(req->request, req->request_len, &k, cmp_name, sizeof(cmp_name))<0) \ + goto err; \ + if (memcmp(tmp_name, cmp_name, strlen (tmp_name)) != 0) \ + return (-1); /* we ignore mismatching names */ \ + } while(0) reply.type = req->request_type; @@ -882,7 +900,7 @@ reply_parse(struct evdns_base *base, u8 *packet, int length) { /* the question looks like * */ - SKIP_NAME; + TEST_NAME; j += 4; if (j > length) goto err; }