From: Wouter Wijngaards Date: Mon, 12 Mar 2007 14:19:14 +0000 (+0000) Subject: Replymsg structure. X-Git-Tag: release-0.2~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=762af9f0a44003fd7406085f941248b28befad9c;p=thirdparty%2Funbound.git Replymsg structure. git-svn-id: file:///svn/unbound/trunk@173 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/Makefile.in b/Makefile.in index 313f2b3ef..7f25edd0e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -50,7 +50,7 @@ LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int INSTALL=$(srcdir)/install-sh -COMMON_SRC=$(wildcard services/*.c util/*.c) util/configparser.c util/configlexer.c testcode/checklocks.c +COMMON_SRC=$(wildcard services/*.c util/*.c util/data/*.c) util/configparser.c util/configlexer.c testcode/checklocks.c COMMON_OBJ=$(addprefix $(BUILD),$(COMMON_SRC:.c=.o)) COMPAT_OBJ=$(addprefix $(BUILD)compat/,$(LIBOBJS)) UNITTEST_SRC=testcode/unitmain.c $(COMMON_SRC) diff --git a/configure.ac b/configure.ac index 5961a2c13..df4bb6931 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ(2.57) -AC_INIT(unbound, 0.1, wouter@nlnetlabs.nl, unbound) +AC_INIT(unbound, 0.2, wouter@nlnetlabs.nl, unbound) CFLAGS= AC_AIX diff --git a/doc/Changelog b/doc/Changelog index d5bd8063f..983ce0de2 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +12 March 2007: Wouter + - configure.ac moved to 0.2. + - query_info and replymsg util/data structure. + 9 March 2007: Wouter - added rwlock writelock checking. So it will keep track of the writelock, and readlocks are enforced diff --git a/testcode/unitmain.c b/testcode/unitmain.c index cf658aa1d..9f97c52e9 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -102,6 +102,36 @@ net_test() unit_assert( !str_is_ip6("255.255.255.0") ); } +/** put dname into buffer */ +static ldns_buffer* +dname_to_buf(ldns_buffer* b, const char* str) +{ + ldns_rdf* rdf; + ldns_status status; + ldns_buffer_clear(b); + rdf = ldns_dname_new_frm_str(str); + status = ldns_dname2buffer_wire(b, rdf); + if(status != LDNS_STATUS_OK) + fatal_exit("%s ldns: %s", __func__, + ldns_get_errorstr_by_id(status)); + ldns_rdf_free(rdf); + ldns_buffer_flip(b); + return b; +} + +#include "util/data/msgreply.h" +/** test query parse code */ +static void +msgreply_test() +{ + ldns_buffer* buff = ldns_buffer_new(65800); + unit_assert( query_dname_len(buff) == 0); + unit_assert( query_dname_len(dname_to_buf(buff, ".")) == 1 ); + unit_assert( query_dname_len(dname_to_buf(buff, "bla.foo.")) == 9 ); + unit_assert( query_dname_len(dname_to_buf(buff, "x.y.z.example.com.")) == 19 ); + ldns_buffer_free(buff); +} + /** * Main unit test program. Setup, teardown and report errors. * @param argc: arg count. @@ -119,6 +149,7 @@ main(int argc, char* argv[]) printf("Start of %s unit test.\n", PACKAGE_STRING); net_test(); alloc_test(); + msgreply_test(); printf("%d tests succeeded\n", testcount); return 0; } diff --git a/util/data/msgreply.c b/util/data/msgreply.c new file mode 100644 index 000000000..db5e9b92d --- /dev/null +++ b/util/data/msgreply.c @@ -0,0 +1,122 @@ +/* + * util/data/msgreply.c - store message and reply data. + * + * Copyright (c) 2007, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * 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 name of the NLNET LABS 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 THE REGENTS OR CONTRIBUTORS 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. + */ + +/** + * \file + * + * This file contains a data structure to store a message and its reply. + */ + +#include "config.h" +#include "util/data/msgreply.h" +#include "util/log.h" + +/** determine length of a dname in buffer, no compression pointers allowed. */ +size_t +query_dname_len(ldns_buffer* query) +{ + size_t len = 0; + size_t labellen; + while(1) { + if(ldns_buffer_remaining(query) < 1) + return 0; /* parse error, need label len */ + labellen = ldns_buffer_read_u8(query); + if(labellen & 0xC0) + return 0; /* no compression allowed in queries */ + len += labellen + 1; + if(len > LDNS_MAX_DOMAINLEN) + return 0; /* too long */ + if(labellen == 0) + return len; + if(ldns_buffer_remaining(query) < labellen) + return 0; /* parse error, need content */ + ldns_buffer_skip(query, (ssize_t)labellen); + } +} + +int query_info_parse(struct query_info* m, ldns_buffer* query) +{ + uint8_t* q = ldns_buffer_begin(query); + /* minimum size: header + \0 + qtype + qclass */ + if(ldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5) + return 0; + log_assert(!LDNS_QR_WIRE(q)); + log_assert(LDNS_OPCODE_WIRE(q) == LDNS_PACKET_QUERY); + log_assert(LDNS_QDCOUNT(q) == 1); + log_assert(ldns_buffer_position(query) == 0); + m->has_cd = (int)LDNS_CD_WIRE(q); + ldns_buffer_skip(query, LDNS_HEADER_SIZE); + m->qname = ldns_buffer_current(query); + m->qnamesize = query_dname_len(query); + if(ldns_buffer_remaining(query) < 4) + return 0; /* need qtype, qclass */ + m->qtype = ldns_buffer_read_u16(query); + m->qclass = ldns_buffer_read_u16(query); + return 1; +} + +/** tiny subroutine for msgreply_compare */ +#define COMPARE_IT(x, y) \ + if( (x) < (y) ) return -1; \ + else if( (x) > (y) ) return +1; \ + log_assert( (x) == (y) ); +int query_info_compare(void* m1, void* m2) +{ + struct query_info* msg1 = (struct query_info*)m1; + struct query_info* msg2 = (struct query_info*)m2; + int mc; + /* from most different to least different for speed */ + COMPARE_IT(msg1->qtype, msg2->qtype); + COMPARE_IT(msg1->qnamesize, msg2->qnamesize); + mc = memcmp(msg1->qname, msg2->qname, msg1->qnamesize); + if(mc != 0) + return mc; + COMPARE_IT(msg1->has_cd, msg2->has_cd); + COMPARE_IT(msg1->qclass, msg2->qclass); + return 0; +#undef COMPARE_IT +} + +void query_info_clear(struct query_info* m) +{ + m->qname = NULL; +} + +void msgreply_clear(struct msgreply* m) +{ + if(m->qname_malloced) + free(m->q.qname); + free(m->reply); +} diff --git a/util/data/msgreply.h b/util/data/msgreply.h new file mode 100644 index 000000000..60d8f62a2 --- /dev/null +++ b/util/data/msgreply.h @@ -0,0 +1,109 @@ +/* + * util/data/msgreply.h - store message and reply data. + * + * Copyright (c) 2007, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * 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 name of the NLNET LABS 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 THE REGENTS OR CONTRIBUTORS 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. + */ + +/** + * \file + * + * This file contains a data structure to store a message and its reply. + */ + +#ifndef UTIL_DATA_MSGREPLY_H +#define UTIL_DATA_MSGREPLY_H + +/** + * Structure to store query information that makes answers to queries + * different. + */ +struct query_info { + /** salient data on the query: qname, in wireformat. */ + uint8_t* qname; + /** length of qname (including last 0 octet) */ + size_t qnamesize; + /** qtype */ + uint16_t qtype; + /** qclass */ + uint16_t qclass; + /** does query have CD bit set */ + int has_cd; +}; + +/** + * Structure to store DNS query and the reply packet. + * To use it, copy over the flags from reply and modify using flags from + * the query (RD,CD if not AA). prepend ID. + */ +struct msgreply { + /** id of this entry. */ + struct query_info q; + /** if q.qname is allocated by malloc or not */ + int qname_malloced; + /** the reply packet, skips ID, starts with flags/opcode/rcode word */ + uint8_t* reply; + /** the reply size */ + size_t replysize; +}; + +/** + * Parse wire query into a queryinfo structure, return 0 on parse error. + * initialises the (prealloced) queryinfo structure as well. sets reply to 0. + * This query structure contains a pointer back info the buffer! + * This pointer avoids memory allocation. + * @param m: the prealloced queryinfo structure to put query into. + * must be unused, or _clear()ed. + * @param query: the wireformat packet query. starts with ID. + * @return: 0 on format error. + */ +int query_info_parse(struct query_info* m, ldns_buffer* query); + +/** + * Compare two queryinfo structures, on query, + * The qname is _not_ sorted in canonical ordering. + * @param m1: struct query_info* , void* here to ease use as function pointer. + * @param m2: struct query_info* , void* here to ease use as function pointer. + * @return: 0 = same, -1 m1 is smaller, +1 m1 is larger. + */ +int query_info_compare(void* m1, void* m2); + +/** clear out query info structure. */ +void query_info_clear(struct query_info* m); + +/** helper routine, determine length of dname in buffer, no compression ptrs + * allowed, returns 0 on failure. */ +size_t query_dname_len(ldns_buffer* query); + +/** clear out msgreply structure */ +void msgreply_clear(struct msgreply* m); + +#endif /* UTIL_DATA_MSGREPLY_H */