From d51196ddc08931f5dcfc29429e6ad4a3695b9c44 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Thu, 5 Apr 2007 14:53:32 +0000 Subject: [PATCH] Results of discussion. git-svn-id: file:///svn/unbound/trunk@231 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 3 ++ doc/TODO | 2 ++ util/data/msgreply.h | 36 ++++++++++++++++++++---- util/data/packed_rrset.h | 59 ++++++++++++++++++++++++++-------------- 4 files changed, 74 insertions(+), 26 deletions(-) diff --git a/doc/Changelog b/doc/Changelog index 05a166cf5..24aa9a078 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,6 @@ +5 April 2007: Wouter + - discussed packed rrset with Jelte. + 4 April 2007: Wouter - moved to version 0.3. - added util/data/dname.c diff --git a/doc/TODO b/doc/TODO index 32a8a6ada..3b1f3d805 100644 --- a/doc/TODO +++ b/doc/TODO @@ -3,3 +3,5 @@ o use real entropy to make random (ID, port) numbers more random. o in production mode, do not free memory on exit. In debug mode, test leaks. o profile memory allocation, and if performance issues, use special memory allocator. For example, with caches per thread. +o #define BIT_... different on bigendian and smallendian systems so that + the htons on flags is not needed to send a message from the cache. diff --git a/util/data/msgreply.h b/util/data/msgreply.h index 7c70cc0dc..ae0e326fe 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -51,7 +51,11 @@ struct alloc_cache; * different. */ struct query_info { - /** salient data on the query: qname, in wireformat. */ + /** + * Salient data on the query: qname, in wireformat. + * can be allocated or a pointer to outside buffer. + * User has to keep track on the status of this. + */ uint8_t* qname; /** length of qname (including last 0 octet) */ size_t qnamesize; @@ -89,9 +93,17 @@ struct reply_info { uint8_t* reply; /** the reply size */ size_t replysize; - /** the flags for the answer, host order. */ + + /** the flags for the answer, host byte order. */ uint16_t flags; + /** + * TTL of the entire reply (for negative caching). + * only for use when there are 0 RRsets in this message. + * if there are RRsets, check those instead. + */ + uint32_t ttl; + /** * network order counts: qdcount ancount nscount arcount. * so this is wireformat for the counts as they appear in the message. @@ -100,14 +112,17 @@ struct reply_info { */ uint16_t counts[4]; - /** Total number of rrsets in reply: ancount+nscount+arcount. */ + /** Total number of rrsets in reply: ancount+nscount+arcount. + * Use the accessor function to get this value. + */ size_t num_rrsets; /** * List of pointers (only) to the rrsets in the order in which - * They appear in the reply message. - * number of elements is ancount+nscount+arcount. - * this is a pointer to that array. + * they appear in the reply message. + * Number of elements is ancount+nscount+arcount. + * This is a pointer to that array. + * Use the accessor function for access. */ struct packed_rrset_key** rrsets; @@ -117,6 +132,15 @@ struct reply_info { * These are sorted in ascending pointer, the locking order. So * this list can be locked (and id, ttl checked), to see if * all the data is available and recent enough. + * + * This is defined as an array of size 1, so that the compiler + * associates the identifier with this position in the structure. + * Array bound overflow on this array then gives access to the further + * elements of the array, which are allocated after the main structure. + * + * It could be more pure to define as array of size 0, ref[0]. + * But ref[1] may be less confusing for compilers. + * Use the accessor function for access. */ struct rrset_ref ref[1]; }; diff --git a/util/data/packed_rrset.h b/util/data/packed_rrset.h index 8592a6933..2b08b9092 100644 --- a/util/data/packed_rrset.h +++ b/util/data/packed_rrset.h @@ -47,6 +47,26 @@ * clearing the cache. */ typedef uint64_t rrset_id_t; +/** + * The identifying information for an RRset. + */ +struct packed_rrset_key { + /** + * The domain name. If not null (for id=0) it is allocated, and + * contains the wireformat domain name. + * This dname is not canonicalized. + * After the dname uint16_t type and uint16_t class is stored + * in wireformat. + * Use accessor functions to get type and class values. + */ + uint8_t* dname; + /** + * Length of the domain name, including last 0 root octet. + * The value+sizeof(uint16_t)*2 is actually allocated. + */ + size_t dname_len; +}; + /** * This structure contains an RRset. A set of resource records that * share the same domain name, type and class. @@ -55,7 +75,7 @@ typedef uint64_t rrset_id_t; * deleted, although the data can be. The id can be set to 0 to store and the * structure can be recycled with a new id. */ -struct packed_rrset_key { +struct ub_packed_rrset_key { /** * entry into hashtable. Note the lock is never destroyed, * even when this key is retired to the cache. @@ -71,20 +91,8 @@ struct packed_rrset_key { * the id (which needs a writelock on entry.lock). */ rrset_id_t id; - - /** - * The domain name. If not null (for id=0) it is allocated, and - * contains the wireformat domain name. - * This dname is canonicalized. - * After the dname uint16_t type and uint16_t class is stored - * in wireformat. - */ - uint8_t* dname; - /** - * Length of the domain name, including last 0 root octet. - * The value+sizeof(uint16_t)*2 is actually allocated. - */ - size_t dname_len; + /** key data: dname, type and class */ + struct packed_rrset_key rk; }; /** @@ -113,11 +121,12 @@ struct packed_rrset_key { * and rr_data starts with the rdlength. * the ttl value to send changes due to time. */ -struct packed_rrset { - /** TTL (in seconds like time()) of the rrset */ +struct packed_rrset_data { + /** TTL (in seconds like time()) of the rrset. + * Same for all RRs see rfc2181(5.2). */ uint32_t ttl; /** number of rrs. */ - size_t num; + size_t count; /** * Array of pointers to every rr's rdata. * The rr_data[i] rdata is stored in uncompressed wireformat. @@ -126,12 +135,22 @@ struct packed_rrset { uint8_t** rr_data; /** length of every rr's rdata, rr_len[i] is size of rr_data[i]. */ size_t* rr_len; - /** TTL of every rr (equal or bigger than the rrset ttl). */ - uint32_t* rr_ttl; /** if this rrset is signed with an RRSIG, it is stored here. */ uint8_t* rrsig_data; /** length of rrsig rdata (only examine if rrsig_data is not null) */ size_t rrsig_len; }; +/** + * An RRset can be represented using both key and data together. + * Split into key and data structures to simplify implementation of + * caching schemes. + */ +struct packed_rrset { + /** domain name, type and class */ + struct packed_rrset_key* k; + /** ttl, count and rdatas (and rrsig) */ + struct packed_rrset_data* d; +}; + #endif /* UTIL_DATA_PACKED_RRSET_H */ -- 2.47.2