Start with wireformat RR iterator

This commit is contained in:
Willem Toorop 2015-02-11 23:51:20 +01:00
parent 6a16a56717
commit 37def257ee
4 changed files with 208 additions and 10 deletions

View File

@ -63,7 +63,7 @@ EXTENSION_LIBUV_LDFLAGS=@EXTENSION_LIBUV_LDFLAGS@
GETDNS_OBJ=const-info.lo convert.lo dict.lo dnssec.lo general.lo \
getdns_error.lo list.lo request-internal.lo \
rr-dict.lo stub.lo sync.lo util-internal.lo
rr-dict.lo rr-iter.lo stub.lo sync.lo util-internal.lo
GLDNS_OBJ=keyraw.lo gbuffer.lo wire2str.lo parse.lo parseutil.lo rrdef.lo \
str2wire.lo
@ -241,16 +241,18 @@ list.lo list.o: $(srcdir)/list.c $(srcdir)/types-internal.h getdns/getdns.h $(sr
request-internal.lo request-internal.o: $(srcdir)/request-internal.c config.h $(srcdir)/types-internal.h \
getdns/getdns.h $(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h \
$(srcdir)/util-internal.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/gldns/rrdef.h
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h
rr-dict.lo rr-dict.o: $(srcdir)/rr-dict.c $(srcdir)/rr-dict.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/context.h config.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/dict.h
rr-iter.lo rr-iter.o: $(srcdir)/rr-iter.c $(srcdir)/rr-iter.h getdns/getdns.h $(srcdir)/gldns/pkthdr.h
stub.lo stub.o: $(srcdir)/stub.c config.h $(srcdir)/stub.h getdns/getdns.h $(srcdir)/types-internal.h \
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/gldns/rrdef.h \
$(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/gbuffer.h $(srcdir)/gldns/pkthdr.h $(srcdir)/context.h \
$(srcdir)/extension/libmini_event.h config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/util-internal.h $(srcdir)/general.h
$(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/util/rbtree.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h $(srcdir)/context.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/util-internal.h \
$(srcdir)/general.h
sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h $(srcdir)/getdns/getdns_extra.h \
getdns/getdns.h $(srcdir)/types-internal.h $(srcdir)/util/rbtree.h $(srcdir)/extension/libmini_event.h \
config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/general.h \
@ -258,7 +260,9 @@ sync.lo sync.o: $(srcdir)/sync.c getdns/getdns.h config.h $(srcdir)/context.h $(
util-internal.lo util-internal.o: $(srcdir)/util-internal.c getdns/getdns.h $(srcdir)/dict.h $(srcdir)/util/rbtree.h \
$(srcdir)/types-internal.h $(srcdir)/getdns/getdns_extra.h getdns/getdns.h $(srcdir)/list.h \
$(srcdir)/util-internal.h $(srcdir)/context.h config.h $(srcdir)/extension/libmini_event.h config.h \
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-dict.h
$(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/types-internal.h $(srcdir)/rr-dict.h \
$(srcdir)/gldns/wire2str.h $(srcdir)/gldns/str2wire.h $(srcdir)/gldns/rrdef.h $(srcdir)/gldns/gbuffer.h \
$(srcdir)/gldns/pkthdr.h
gbuffer.lo gbuffer.o: $(srcdir)/gldns/gbuffer.c config.h $(srcdir)/gldns/gbuffer.h
keyraw.lo keyraw.o: $(srcdir)/gldns/keyraw.c config.h $(srcdir)/gldns/keyraw.h $(srcdir)/gldns/rrdef.h
parse.lo parse.o: $(srcdir)/gldns/parse.c config.h $(srcdir)/gldns/parse.h $(srcdir)/gldns/parseutil.h \

127
src/rr-iter.c Normal file
View File

@ -0,0 +1,127 @@
/**
*
* /brief RR iterator over wireformat DNS packet
*/
/*
* Copyright (c) 2013, NLnet Labs, Verisign, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the names of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "rr-iter.h"
#include "config.h"
#include <gldns/pkthdr.h>
#include <gldns/gbuffer.h>
static getdns_rr_iter *
find_rrtype(getdns_rr_iter *i)
{
size_t dlen;
uint8_t *pos;
/* Past the last RR in the pkt */
if (GLDNS_QDCOUNT(i->pkt) + GLDNS_ANCOUNT(i->pkt) +
GLDNS_NSCOUNT(i->pkt) + GLDNS_ARCOUNT(i->pkt) <= i->n) {
i->pos = NULL;
return NULL;
}
/* This iterator was already done */
if (!i->pos)
return NULL;
pos = i->pos;
dlen = i->pkt_len - (pos - i->pkt);
while (dlen >= 5) { /* At least space for type and class */
if (*pos == 0) {
i->rr_type = pos + 1;
return i;
}
if ((*pos & 0xC0) == 0xC0) {
i->rr_type = pos + 2;
return i;
}
if ((*pos & 0xC0) != 0)
break; /* Unknown label type */
if (*pos > dlen)
break; /* Label size overflows packet size! */
dlen -= *pos + 1;
pos += *pos + 1;
}
i->pos = NULL;
return NULL;
}
getdns_rr_iter *
priv_getdns_rr_iter_init(getdns_rr_iter *i, uint8_t *pkt, size_t pkt_len)
{
if (pkt_len < GLDNS_HEADER_SIZE + 5)
return NULL;
i->pkt = pkt;
i->pkt_len = pkt_len;
i->n = 0;
i->pos = pkt + GLDNS_HEADER_SIZE;
return find_rrtype(i);
}
getdns_rr_iter *
priv_getdns_rr_iter_next(getdns_rr_iter *i)
{
size_t dlen;
/* Already done */
if (!i->pos)
return NULL;
assert(i->rr_type);
i->n += 1;
if (i->n <= GLDNS_QDCOUNT(i->pkt)) {
i->pos = i->rr_type + 4;
return find_rrtype(i);
}
dlen = i->pkt_len - (i->rr_type - i->pkt);
if (dlen < 10)
goto garbage; /* No space for type, class, ttl & rdlength */
if (gldns_read_uint16(i->rr_type + 8) > dlen - 10)
goto garbage; /* RData size overflos packet size */
i->pos = i->rr_type + 10 + gldns_read_uint16(i->rr_type + 8);
return find_rrtype(i);
garbage:
i->pos = NULL;
return NULL;
}

52
src/rr-iter.h Normal file
View File

@ -0,0 +1,52 @@
/**
*
* /brief RR iterator over wireformat DNS packet
*/
/*
* Copyright (c) 2013, NLnet Labs, Verisign, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the names of the copyright holders nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef RR_ITER_H_
#define RR_ITER_H_
#include "getdns/getdns.h"
typedef struct getdns_rr_iter {
uint8_t *pkt;
size_t pkt_len;
size_t n; /* Which RR are we currently at */
uint8_t *pos;
uint8_t *rr_type;
} getdns_rr_iter;
getdns_rr_iter *priv_getdns_rr_iter_init(getdns_rr_iter *i,
uint8_t *pkt, size_t pkt_len);
getdns_rr_iter *priv_getdns_rr_iter_next(getdns_rr_iter *i);
#endif
/* rrs.h */

View File

@ -51,6 +51,7 @@
#include "gldns/str2wire.h"
#include "gldns/gbuffer.h"
#include "gldns/pkthdr.h"
#include "rr-iter.h"
/**
* this is a comprehensive list of extensions and their data types
@ -503,9 +504,9 @@ create_getdns_response(getdns_dns_req *completed_request)
/* info (bools) about dns_req */
int dnssec_return_status;
#if defined(WIRE_DEBUG) && WIRE_DEBUG
char *str_pkt;
getdns_rr_iter rr_iter_storage, *rr_iter;
for ( netreq_p = completed_request->netreqs
; ! r && (netreq = *netreq_p)
; netreq_p++) {
@ -521,13 +522,27 @@ create_getdns_response(getdns_dns_req *completed_request)
continue;
}
#if defined(WIRE_DEBUG) && WIRE_DEBUG
for ( rr_iter = priv_getdns_rr_iter_init(&rr_iter_storage
, netreq->response
, netreq->response_len)
; rr_iter
; rr_iter = priv_getdns_rr_iter_next(rr_iter)) {
fprintf( stderr, "n: %d, dname: %p, rr_type: %p "
"-> type: %d, class: %d\n"
, (int)rr_iter->n,rr_iter->pos,rr_iter->rr_type
, (int)gldns_read_uint16(rr_iter->rr_type)
, (int)gldns_read_uint16(rr_iter->rr_type + 2)
);
}
if ((str_pkt = gldns_wire2str_pkt(
netreq->response, netreq->response_len))) {
fprintf(stderr, "%s\n", str_pkt);
free(str_pkt);
}
}
#endif
}
dnssec_return_status = completed_request->dnssec_return_status ||
completed_request->dnssec_return_only_secure;