Skip to content

Commit

Permalink
Fix parsing of multiple records.
Browse files Browse the repository at this point in the history
  • Loading branch information
vstakhov committed Apr 3, 2014
1 parent d006420 commit cc5f39e
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 16 deletions.
7 changes: 4 additions & 3 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ rdns_request_reply_cmp (struct rdns_request *req, uint8_t *in, int len)

/* In p we would store current position in reply and in c - position in request */
p = in;
c = req->packet + sizeof (struct dns_header);
c = req->packet + req->pos;

for (;;) {
/* Get current label */
Expand All @@ -83,8 +83,8 @@ rdns_request_reply_cmp (struct rdns_request *req, uint8_t *in, int len)
p += len1;
}
if (len2 & DNS_COMPRESSION_BITS) {
len2 = UNCOMPRESS_DNS_OFFSET(p);
l2 = rdns_decompress_label (req->packet, &len2, len);
len2 = UNCOMPRESS_DNS_OFFSET(c);
l2 = rdns_decompress_label (c, &len2, len);
if (l2 == NULL) {
rdns_info ("invalid DNS pointer, cannot decompress");
return NULL;
Expand Down Expand Up @@ -115,6 +115,7 @@ rdns_request_reply_cmp (struct rdns_request *req, uint8_t *in, int len)
/* p now points to the end of QR section */
/* Compare class and type */
if (memcmp (p, c, sizeof (uint16_t) * 2) == 0) {
req->pos = c - req->packet + sizeof (uint16_t) * 2;
return p + sizeof (uint16_t) * 2;
}
return NULL;
Expand Down
24 changes: 19 additions & 5 deletions src/resolver.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,9 @@ rdns_parse_reply (uint8_t *in, int r, struct rdns_request *req,
struct dns_header *header = (struct dns_header *)in;
struct rdns_reply *rep;
struct rdns_reply_entry *elt;
uint8_t *pos;
uint8_t *pos, *npos;
struct rdns_resolver *resolver = req->resolver;
uint16_t qdcount;

int i, t;

Expand All @@ -160,14 +161,27 @@ rdns_parse_reply (uint8_t *in, int r, struct rdns_request *req,
return false;
}

qdcount = ntohs (header->qdcount);

if (qdcount != req->qcount) {
rdns_info ("request has %d queries, reply has %d queries", (int)req->qcount, (int)header->qdcount);
return false;
}

/*
* Now we have request and query data is now at the end of header, so compare
* request QR section and reply QR section
*/
if ((pos = rdns_request_reply_cmp (req, in + sizeof (struct dns_header),
r - sizeof (struct dns_header))) == NULL) {
rdns_info ("DNS request with id %d is for different query, ignoring", (int)req->id);
return false;
req->pos = sizeof (struct dns_header);
pos = in + sizeof (struct dns_header);
t = r - sizeof (struct dns_header);
for (i = 0; i < (int)qdcount; i ++) {
if ((npos = rdns_request_reply_cmp (req, pos,t)) == NULL) {
rdns_info ("DNS request with id %d is for different query, ignoring", (int)req->id);
return false;
}
t -= npos - pos;
pos = npos;
}
/*
* Now pos is in answer section, so we should extract data and form reply
Expand Down
16 changes: 8 additions & 8 deletions test/dns_regress.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,18 +85,18 @@ static void
rdns_test_a (struct rdns_resolver *resolver)
{
const char *names[] = {
"google.com",
"github.com",
//"google.com",
//"github.com",
"freebsd.org",
"kernel.org",
"www.ник.рф",
//"kernel.org",
//"www.ник.рф",
NULL
};
const char **cur;

for (cur = names; *cur != NULL; cur ++) {
rdns_make_request_full (resolver, rdns_regress_callback, *cur, 1.0, 2, 1,
*cur, RDNS_REQUEST_AAAA);
rdns_make_request_full (resolver, rdns_regress_callback, *cur, 1.0, 2, 2,
*cur, RDNS_REQUEST_AAAA, *cur, RDNS_REQUEST_A);
remain_tests ++;
}
}
Expand Down Expand Up @@ -137,8 +137,8 @@ main (int argc, char **argv)
rdns_bind_libevent (resolver_event, base);
rdns_resolver_set_log_level (resolver_event, RDNS_LOG_DEBUG);
/* Google and opendns */
assert (rdns_resolver_add_server (resolver_event, "208.67.222.222", 53, 0, 8));
assert (rdns_resolver_add_server (resolver_event, "8.8.8.8", 53, 0, 1));
assert (rdns_resolver_add_server (resolver_event, "127.0.0.1", 53, 0, 8));
//assert (rdns_resolver_add_server (resolver_event, "8.8.8.8", 53, 0, 1));

assert (rdns_resolver_init (resolver_ev));
assert (rdns_resolver_init (resolver_event));
Expand Down

0 comments on commit cc5f39e

Please sign in to comment.