]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Compare the query sesion of DNS responses to the actual query to ensure
authorhno <>
Tue, 10 May 2005 16:09:31 +0000 (16:09 +0000)
committerhno <>
Tue, 10 May 2005 16:09:31 +0000 (16:09 +0000)
there is no overlaps between queries using the same ID.

include/rfc1035.h
lib/rfc1035.c
src/dns_internal.cc

index 718a7ed81bfb576c7dff7648035acc5ed6780569..9b89bf16d4de2397c42ad57db44c2b165c651676 100644 (file)
@@ -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;
index 5abaca1796bb0ab1bac8a188df39ae96475874a3..7859e9d84ecff32cea65e91e42d8aad6262f6e08 100644 (file)
@@ -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;
 }
index ecbaf9fec9118ddd505b554f6ed9768482aadddf..94e654b97f834f219b57059fb787ede6107e2ec5 100644 (file)
@@ -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);
 }