From: hno <> Date: Tue, 10 May 2005 16:09:31 +0000 (+0000) Subject: Compare the query sesion of DNS responses to the actual query to ensure X-Git-Tag: SQUID_3_0_PRE4~755 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9e1f210d558c5787b19cf64ec07aa5258ce92e86;p=thirdparty%2Fsquid.git Compare the query sesion of DNS responses to the actual query to ensure there is no overlaps between queries using the same ID. --- diff --git a/include/rfc1035.h b/include/rfc1035.h index 718a7ed81b..9b89bf16d4 100644 --- a/include/rfc1035.h +++ b/include/rfc1035.h @@ -1,5 +1,5 @@ /* - * $Id: rfc1035.h,v 1.13 2005/05/10 08:23:06 hno Exp $ + * $Id: rfc1035.h,v 1.14 2005/05/10 10:09:31 hno Exp $ * * AUTHOR: Duane Wessels * @@ -83,15 +83,18 @@ struct _rfc1035_message { SQUIDCEXTERN ssize_t rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, - unsigned short qid); + unsigned short qid, + rfc1035_query *query); SQUIDCEXTERN ssize_t rfc1035BuildPTRQuery(const struct IN_ADDR, char *buf, size_t sz, - unsigned short qid); + unsigned short qid, + rfc1035_query *query); SQUIDCEXTERN void rfc1035SetQueryID(char *, unsigned short qid); SQUIDCEXTERN int rfc1035MessageUnpack(const char *buf, size_t sz, rfc1035_message ** answer); +SQUIDCEXTERN int rfc1035QueryCompare(const rfc1035_query *, const rfc1035_query *); SQUIDCEXTERN void rfc1035MessageDestroy(rfc1035_message * message); SQUIDCEXTERN int rfc1035_errno; SQUIDCEXTERN const char *rfc1035_error_message; diff --git a/lib/rfc1035.c b/lib/rfc1035.c index 5abaca1796..7859e9d84e 100644 --- a/lib/rfc1035.c +++ b/lib/rfc1035.c @@ -1,6 +1,6 @@ /* - * $Id: rfc1035.c,v 1.42 2005/05/10 08:23:07 hno Exp $ + * $Id: rfc1035.c,v 1.43 2005/05/10 10:09:32 hno Exp $ * * Low level DNS protocol routines * AUTHOR: Duane Wessels @@ -393,7 +393,7 @@ rfc1035RRUnpack(const char *buf, size_t sz, off_t * off, rfc1035_rr * RR) case RFC1035_TYPE_PTR: RR->rdata = xmalloc(RFC1035_MAXHOSTNAMESZ); rdata_off = *off; - RR->rdlength = 0; /* Filled in by rfc1035NameUnpack */ + RR->rdlength = 0; /* Filled in by rfc1035NameUnpack */ if (rfc1035NameUnpack(buf, sz, &rdata_off, &RR->rdlength, RR->rdata, RFC1035_MAXHOSTNAMESZ, 0)) return 1; if (rdata_off > ((*off) + rdlength)) { @@ -403,7 +403,7 @@ rfc1035RRUnpack(const char *buf, size_t sz, off_t * off, rfc1035_rr * RR) * the RDATA area. */ RFC1035_UNPACK_DEBUG; - xfree(RR->rdata); + xfree(RR->rdata); memset(RR, '\0', sizeof(*RR)); return 1; } @@ -494,17 +494,15 @@ rfc1035QueryUnpack(const char *buf, size_t sz, off_t * off, rfc1035_query * quer } memcpy(&s, buf + *off, 2); *off += 2; - buf+=2; query->qtype = ntohs(s); memcpy(&s, buf + *off, 2); *off += 2; - buf+=2; - query->qtype = ntohs(s); + query->qclass = ntohs(s); return 0; } -void -rfc1035MessageDestroy(rfc1035_message *msg) +void +rfc1035MessageDestroy(rfc1035_message * msg) { if (!msg) return; @@ -515,6 +513,23 @@ rfc1035MessageDestroy(rfc1035_message *msg) xfree(msg); } +/* + * rfc1035QueryCompare() + * + * Compares two rfc1035_query entries + * + * Returns 0 (equal) or !=0 (different) + */ +int +rfc1035QueryCompare(const rfc1035_query * a, const rfc1035_query * b) +{ + if (a->qtype != b->qtype) + return 1; + if (a->qclass != b->qclass) + return 1; + return strcmp(a->name, b->name); +} + /* * rfc1035MessageUnpack() * @@ -560,8 +575,8 @@ rfc1035MessageUnpack(const char *buf, xfree(msg); return -rfc1035_unpack_error; } - querys = msg->query = xcalloc((int)msg->qdcount, sizeof(*querys)); - for (i = 0; i < (int)msg->qdcount; i++) { + querys = msg->query = xcalloc((int) msg->qdcount, sizeof(*querys)); + for (i = 0; i < (int) msg->qdcount; i++) { if (rfc1035QueryUnpack(buf, sz, &off, &querys[i])) { RFC1035_UNPACK_DEBUG; rfc1035SetErrno(rfc1035_unpack_error); @@ -572,8 +587,8 @@ rfc1035MessageUnpack(const char *buf, *answer = msg; if (msg->ancount == 0) return 0; - recs = msg->answer = xcalloc((int)msg->ancount, sizeof(*recs)); - for (i = 0; i < (int)msg->ancount; i++) { + recs = msg->answer = xcalloc((int) msg->ancount, sizeof(*recs)); + for (i = 0; i < (int) msg->ancount; i++) { if (off >= sz) { /* corrupt packet */ RFC1035_UNPACK_DEBUG; break; @@ -608,7 +623,7 @@ rfc1035MessageUnpack(const char *buf, * Returns the size of the query */ ssize_t -rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid) +rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qid, rfc1035_query * query) { static rfc1035_message h; size_t offset = 0; @@ -624,6 +639,11 @@ rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qi hostname, RFC1035_TYPE_A, RFC1035_CLASS_IN); + if (query) { + query->qtype = RFC1035_TYPE_A; + query->qclass = RFC1035_CLASS_IN; + xstrncpy(query->name, hostname, sizeof(query->name)); + } assert(offset <= sz); return offset; } @@ -639,7 +659,7 @@ rfc1035BuildAQuery(const char *hostname, char *buf, size_t sz, unsigned short qi * Return value is the query ID. */ ssize_t -rfc1035BuildPTRQuery(const struct IN_ADDR addr, char *buf, size_t sz, unsigned short qid) +rfc1035BuildPTRQuery(const struct IN_ADDR addr, char *buf, size_t sz, unsigned short qid, rfc1035_query * query) { static rfc1035_message h; size_t offset = 0; @@ -663,6 +683,11 @@ rfc1035BuildPTRQuery(const struct IN_ADDR addr, char *buf, size_t sz, unsigned s rev, RFC1035_TYPE_PTR, RFC1035_CLASS_IN); + if (query) { + query->qtype = RFC1035_TYPE_PTR; + query->qclass = RFC1035_CLASS_IN; + xstrncpy(query->name, rev, sizeof(query->name)); + } assert(offset <= sz); return offset; } diff --git a/src/dns_internal.cc b/src/dns_internal.cc index ecbaf9fec9..94e654b97f 100644 --- a/src/dns_internal.cc +++ b/src/dns_internal.cc @@ -1,6 +1,6 @@ /* - * $Id: dns_internal.cc,v 1.73 2005/05/10 08:23:07 hno Exp $ + * $Id: dns_internal.cc,v 1.74 2005/05/10 10:09:32 hno Exp $ * * DEBUG: section 78 DNS lookups; interacts with lib/rfc1035.c * AUTHOR: Duane Wessels @@ -64,7 +64,7 @@ typedef struct _ns ns; struct _idns_query { hash_link hash; - char query[RFC1035_MAXHOSTNAMESZ+1]; + rfc1035_query query; char buf[512]; size_t sz; unsigned short id; @@ -615,14 +615,20 @@ idnsGrokReply(const char *buf, size_t sz) q = idnsFindQuery(message->id); - /* FIXME: We should also verify the query to match ours */ - if (q == NULL) { debug(78, 3) ("idnsGrokReply: Late response\n"); rfc1035MessageDestroy(message); return; } + /* FIXME: We should also verify the query to match ours */ + if (rfc1035QueryCompare(&q->query, message->query) != 0) { + debug(78, 3) ("idnsGrokReply: Query mismatch (%s != %s)\n", q->query.name, message->query->name); + rfc1035MessageDestroy(message); + return; + } + + dlinkDelete(&q->lru, &lru_list); idnsRcodeCount(n, q->attempt); q->error = NULL; @@ -912,10 +918,9 @@ idnsCachedLookup(const char *key, IDNSCB * callback, void *data) } static void -idnsCacheQuery(idns_query *q, const char *key) +idnsCacheQuery(idns_query *q) { - xstrncpy(q->query, key, sizeof(q->query)); - q->hash.key = q->query; + q->hash.key = q->query.name; hash_join(idns_lookup_hash, &q->hash); } @@ -931,7 +936,7 @@ idnsALookup(const char *name, IDNSCB * callback, void *data) q->id = idnsQueryID(); - q->sz = rfc1035BuildAQuery(name, q->buf, sizeof(q->buf), q->id); + q->sz = rfc1035BuildAQuery(name, q->buf, sizeof(q->buf), q->id, &q->query); debug(78, 3) ("idnsALookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, name, q->id); @@ -942,7 +947,7 @@ idnsALookup(const char *name, IDNSCB * callback, void *data) q->start_t = current_time; - idnsCacheQuery(q, name); + idnsCacheQuery(q); idnsSendQuery(q); } @@ -962,7 +967,7 @@ idnsPTRLookup(const struct IN_ADDR addr, IDNSCB * callback, void *data) q->id = idnsQueryID(); - q->sz = rfc1035BuildPTRQuery(addr, q->buf, sizeof(q->buf), q->id); + q->sz = rfc1035BuildPTRQuery(addr, q->buf, sizeof(q->buf), q->id, &q->query); debug(78, 3) ("idnsPTRLookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, ip, q->id); @@ -973,7 +978,7 @@ idnsPTRLookup(const struct IN_ADDR addr, IDNSCB * callback, void *data) q->start_t = current_time; - idnsCacheQuery(q, ip); + idnsCacheQuery(q); idnsSendQuery(q); }