/*
- * $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
*
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;
/*
- * $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
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)) {
* the RDATA area.
*/
RFC1035_UNPACK_DEBUG;
- xfree(RR->rdata);
+ xfree(RR->rdata);
memset(RR, '\0', sizeof(*RR));
return 1;
}
}
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;
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()
*
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);
*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;
* 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;
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;
}
* 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;
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;
}
/*
- * $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
struct _idns_query
{
hash_link hash;
- char query[RFC1035_MAXHOSTNAMESZ+1];
+ rfc1035_query query;
char buf[512];
size_t sz;
unsigned short id;
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;
}
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);
}
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);
q->start_t = current_time;
- idnsCacheQuery(q, name);
+ idnsCacheQuery(q);
idnsSendQuery(q);
}
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);
q->start_t = current_time;
- idnsCacheQuery(q, ip);
+ idnsCacheQuery(q);
idnsSendQuery(q);
}