diff options
author | Internet Software Consortium, Inc <@isc.org> | 2007-09-07 14:08:43 -0600 |
---|---|---|
committer | LaMont Jones <lamont@debian.org> | 2007-09-07 14:08:43 -0600 |
commit | 845c529daf861c03794b0fb8085ff2ab51adf99b (patch) | |
tree | ecb328a6b57fb4cd53a9f2b4f8959ddabff87856 /lib | |
parent | c380ae240a9a3b5e71bfb604936b73aae6a49d5e (diff) | |
download | bind9-845c529daf861c03794b0fb8085ff2ab51adf99b.tar.gz |
9.1.0b3
Diffstat (limited to 'lib')
-rw-r--r-- | lib/dns/compress.c | 391 | ||||
-rw-r--r-- | lib/dns/config/confparser.y | 38 | ||||
-rw-r--r-- | lib/dns/include/dns/compress.h | 97 | ||||
-rw-r--r-- | lib/dns/message.c | 8 | ||||
-rw-r--r-- | lib/dns/name.c | 13 | ||||
-rw-r--r-- | lib/dns/request.c | 51 | ||||
-rw-r--r-- | lib/dns/resolver.c | 41 | ||||
-rw-r--r-- | lib/dns/zone.c | 46 | ||||
-rw-r--r-- | lib/isc/unix/include/isc/net.h | 28 | ||||
-rw-r--r-- | lib/tests/t_api.c | 3 |
10 files changed, 334 insertions, 382 deletions
diff --git a/lib/dns/compress.c b/lib/dns/compress.c index 4857014e..cdc9e0eb 100644 --- a/lib/dns/compress.c +++ b/lib/dns/compress.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.c,v 1.36 2000/11/14 23:29:49 bwelling Exp $ */ +/* $Id: compress.c,v 1.36.4.1 2001/01/06 01:33:31 gson Exp $ */ #define DNS_NAME_USEINLINE 1 @@ -36,53 +36,48 @@ #define DCTX_MAGIC 0x44435458U /* DCTX */ #define VALID_DCTX(x) ISC_MAGIC_VALID(x, DCTX_MAGIC) -static void -free_offset(void *offset, void *mctx); - -static isc_boolean_t -compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix, - dns_name_t *suffix, isc_uint16_t *offset, - isc_buffer_t *workspace); - -static void -compress_add(dns_rbt_t *root, dns_name_t *prefix, dns_name_t *suffix, - isc_uint16_t offset, isc_boolean_t global16, isc_mem_t *mctx); - /*** *** Compression ***/ isc_result_t dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) { - isc_result_t result; + unsigned int i; REQUIRE(cctx != NULL); REQUIRE(mctx != NULL); cctx->allowed = 0; - cctx->rdata = 0; - cctx->global16 = ISC_FALSE; cctx->edns = edns; - cctx->global = NULL; - result = dns_rbt_create(mctx, free_offset, mctx, &cctx->global); - if (result != ISC_R_SUCCESS) - return (result); + for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) + cctx->table[i] = NULL; cctx->mctx = mctx; + cctx->count = 0; cctx->magic = CCTX_MAGIC; return (ISC_R_SUCCESS); } void dns_compress_invalidate(dns_compress_t *cctx) { + dns_compressnode_t *node; + unsigned int i; REQUIRE(VALID_CCTX(cctx)); cctx->magic = 0; - if (cctx->global != NULL) - dns_rbt_destroy(&cctx->global); + if (cctx->table != NULL) { + for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { + while (cctx->table[i] != NULL) { + node = cctx->table[i]; + cctx->table[i] = cctx->table[i]->next; + if (node->count < DNS_COMPRESS_INITIALNODES) + continue; + isc_mem_put(cctx->mctx, node, + sizeof(dns_compressnode_t)); + } + } + } cctx->allowed = 0; - cctx->rdata = 0; - cctx->global16 = ISC_FALSE; cctx->edns = -1; } @@ -105,89 +100,137 @@ dns_compress_getedns(dns_compress_t *cctx) { return (cctx->edns); } +/* + * Find the longest match of name in the table. + * If match is found return ISC_TRUE. prefix, suffix and offset are updated. + * If no match is found return ISC_FALSE. + */ isc_boolean_t dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, dns_name_t *prefix, dns_name_t *suffix, - isc_uint16_t *offset, isc_buffer_t *workspace) + isc_uint16_t *offset) { + dns_name_t tname, nname; + dns_compressnode_t *node = NULL; + unsigned int labels, hash, n; + REQUIRE(VALID_CCTX(cctx)); REQUIRE(dns_name_isabsolute(name) == ISC_TRUE); REQUIRE(offset != NULL); - return (compress_find(cctx->global, name, prefix, suffix, offset, - workspace)); + labels = dns_name_countlabels(name); + INSIST(labels > 0); + + dns_name_init(&tname, NULL); + dns_name_init(&nname, NULL); + + for (n = 0; n < labels - 1; n++) { + dns_name_getlabelsequence(name, n, labels - n, &tname); + hash = dns_name_hash(&tname, ISC_FALSE) % + DNS_COMPRESS_TABLESIZE; + for (node = cctx->table[hash]; node != NULL; node = node->next) + { + dns_name_fromregion(&nname, &node->r); + if (dns_name_equal(&nname, &tname)) + break; + } + if (node != NULL) + break; + } + + /* + * If node == NULL, we found no match at all. + */ + if (node == NULL) + return (ISC_FALSE); + + dns_name_clone(&tname, suffix); + dns_name_getlabelsequence(name, 0, n, prefix); + *offset = node->offset; + return (ISC_TRUE); } void -dns_compress_add(dns_compress_t *cctx, dns_name_t *prefix, - dns_name_t *suffix, isc_uint16_t offset) +dns_compress_add(dns_compress_t *cctx, dns_name_t *name, dns_name_t *prefix, + isc_uint16_t offset) { + dns_name_t tname, nname; + dns_label_t label; + unsigned int start; + unsigned int n; + unsigned int count; + unsigned int hash; + dns_compressnode_t *node; + REQUIRE(VALID_CCTX(cctx)); + REQUIRE(dns_name_isabsolute(name)); - compress_add(cctx->global, prefix, suffix, offset, - cctx->global16, cctx->mctx); + dns_name_init(&tname, NULL); + dns_name_init(&nname, NULL); + + n = dns_name_countlabels(name); + count = dns_name_countlabels(prefix); + if (dns_name_isabsolute(prefix)) + count--; + start = 0; + while (count > 0) { + if (offset >= 0x4000) + break; + dns_name_getlabelsequence(name, start, n, &tname); + hash = dns_name_hash(&tname, ISC_FALSE) % + DNS_COMPRESS_TABLESIZE; + /* + * Look for the name in the hash bucket. If it's there, + * we're done. + */ + for (node = cctx->table[hash]; node != NULL; node = node->next) + { + dns_name_fromregion(&nname, &node->r); + if (dns_name_equal(&nname, &tname)) + return; + } + /* + * It's not there. Create a new node and add it. + */ + if (cctx->count < DNS_COMPRESS_INITIALNODES) + node = &cctx->initialnodes[cctx->count]; + else { + node = isc_mem_get(cctx->mctx, + sizeof(dns_compressnode_t)); + if (node == NULL) + return; + } + node->count = cctx->count++; + node->offset = offset; + dns_name_toregion(&tname, &node->r); + node->next = cctx->table[hash]; + cctx->table[hash] = node; + dns_name_getlabel(&tname, 0, &label); + offset += label.length; + start++; + n--; + count--; + } } void dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset) { - dns_rbtnode_t *node; - dns_fixedname_t foundfixed; - dns_fixedname_t fullfixed; - dns_fixedname_t originfixed; - dns_name_t *foundname; - dns_name_t *fullname; - dns_name_t *origin; - dns_rbtnodechain_t chain; - isc_result_t result; + unsigned int i; + dns_compressnode_t *node; REQUIRE(VALID_CCTX(cctx)); - /* - * Initalise things. - */ - dns_fixedname_init(&foundfixed); - foundname = dns_fixedname_name(&foundfixed); - dns_fixedname_init(&fullfixed); - fullname = dns_fixedname_name(&fullfixed); - dns_fixedname_init(&originfixed); - origin = dns_fixedname_name(&originfixed); - dns_rbtnodechain_init(&chain, cctx->mctx); - - again: - result = dns_rbtnodechain_first(&chain, cctx->global, foundname, - origin); - - while (result == DNS_R_NEWORIGIN || result == ISC_R_SUCCESS) { - result = dns_rbtnodechain_current(&chain, foundname, - origin, &node); - - if (result != ISC_R_SUCCESS) - break; - - if (node->data != NULL && - (*(isc_uint16_t*)node->data >= offset)) { - result = dns_name_concatenate(foundname, - dns_name_isabsolute(foundname) ? - NULL : origin, - fullname, NULL); - - if (result != ISC_R_SUCCESS) - break; - - result = dns_rbt_deletename(cctx->global, fullname, - ISC_FALSE); - if (result != ISC_R_SUCCESS) - break; - /* - * If the delete is successful the chain is broken. - */ - dns_rbtnodechain_reset(&chain); - goto again; + for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) { + node = cctx->table[i]; + while (node != NULL && node->offset >= offset) { + cctx->table[i] = node->next; + if (node->count >= DNS_COMPRESS_INITIALNODES) + isc_mem_put(cctx->mctx, node, + sizeof(dns_compressnode_t)); + cctx->count--; + node = cctx->table[i]; } - - result = dns_rbtnodechain_next(&chain, foundname, origin); } - dns_rbtnodechain_invalidate(&chain); } /*** @@ -204,7 +247,6 @@ dns_decompress_init(dns_decompress_t *dctx, int edns, dctx->allowed = DNS_COMPRESS_NONE; dctx->edns = edns; dctx->type = type; - dctx->rdata = 0; dctx->magic = DCTX_MAGIC; } @@ -257,182 +299,3 @@ dns_decompress_type(dns_decompress_t *dctx) { return (dctx->type); } - -/*** - *** Private - ***/ - -static void -free_offset(void *offset, void *mctx) { - REQUIRE(offset != NULL); - REQUIRE(mctx != NULL); - isc_mem_put(mctx, offset, sizeof(isc_uint16_t)); -} - -/* - * Add the labels in prefix to RBT. - */ -static void -compress_add(dns_rbt_t *root, dns_name_t *prefix, dns_name_t *suffix, - isc_uint16_t offset, isc_boolean_t global16, isc_mem_t *mctx) -{ - - dns_name_t name; - dns_name_t full; - dns_label_t label; - unsigned int count; - unsigned int start; - unsigned int n; - isc_uint16_t *data; - isc_result_t result; - unsigned char buffer[255]; - isc_buffer_t target; - dns_offsets_t offsets; - - count = dns_name_countlabels(prefix); - if (dns_name_isabsolute(prefix)) - count--; - start = 0; - dns_name_init(&full, offsets); - dns_name_init(&name, NULL); - isc_buffer_init(&target, buffer, sizeof(buffer)); - result = dns_name_concatenate(prefix, suffix, &full, &target); - if (result != ISC_R_SUCCESS) - return; - n = dns_name_countlabels(&full); - while (count > 0) { - if (offset >= 16384 && !global16) - break; - dns_name_getlabelsequence(&full, start, n, &name); - data = isc_mem_get(mctx, sizeof *data); - if (data == NULL) - return; - *data = offset; - result = dns_rbt_addname(root, &name, data); - if (result != ISC_R_SUCCESS) { - isc_mem_put(mctx, data, sizeof *data); - return; - } - dns_name_getlabel(&name, 0, &label); - offset += label.length; - start++; - n--; - count--; - } -} - -/* - * Find the longest match of name in root. - * If match is found return ISC_TRUE. prefix, suffix and offset - * are updated. - * If no match is found return ISC_FALSE. - */ - -static isc_boolean_t -compress_find(dns_rbt_t *root, dns_name_t *name, dns_name_t *prefix, - dns_name_t *suffix, isc_uint16_t *offset, - isc_buffer_t *workspace) -{ - dns_fixedname_t found; - dns_name_t *foundname; - dns_name_t tmpprefix; - dns_name_t tmpsuffix; - isc_result_t result; - isc_uint16_t *data = NULL; - dns_label_t foundlabel; - dns_label_t namelabel; - unsigned int foundlabels; - unsigned int namelabels; - unsigned int foundbits; - unsigned int namebits; - unsigned int bits; - unsigned int prefixlen; - unsigned int j; - unsigned char buf[2 + 256/8]; /* size of biggest bit label */ - dns_bitlabel_t bit; - isc_region_t region; - - dns_fixedname_init(&found); - foundname = dns_fixedname_name(&found); - /* - * Getting rid of the offsets table for foundname improves - * perfomance, since the offsets table is not needed and maintaining - * it has costs. - */ - foundname->offsets = NULL; - result = dns_rbt_findname(root, name, 0, foundname, (void *)&data); - if (result != ISC_R_SUCCESS && result != DNS_R_PARTIALMATCH) - return (ISC_FALSE); - if (data == NULL) /* root label */ - return (ISC_FALSE); - /* - * Do we have to do bit string processing? - */ - dns_name_getlabel(foundname, 0, &foundlabel); - foundlabels = dns_name_countlabels(foundname); - INSIST(foundlabels > 1); /* root labels are not added to tree */ - namelabels = dns_name_countlabels(name); - if (dns_label_type(&foundlabel) == dns_labeltype_bitstring) { - dns_name_getlabel(name, namelabels - foundlabels, &namelabel); - INSIST(dns_label_type(&namelabel) == dns_labeltype_bitstring); - foundbits = dns_label_countbits(&foundlabel); - namebits = dns_label_countbits(&namelabel); - } else - namebits = foundbits = 0; - - if (namebits == foundbits) { - INSIST(namelabels >= foundlabels); - prefixlen = namelabels - foundlabels; - if (prefixlen == 0) { - prefix->length = 0; - prefix->labels = 0; - } else - dns_name_getlabelsequence(name, 0, prefixlen, prefix); - result = dns_name_concatenate(NULL, foundname, suffix, - workspace); - if (result != ISC_R_SUCCESS) - return (ISC_FALSE); - *offset = *data; - return (ISC_TRUE); - } - /* - * At this stage we have a bit string label to split in two. - * There is potentially a prefix before this label and definitly - * a suffix after it (if only the root). - */ - INSIST(result == DNS_R_PARTIALMATCH); - result = dns_name_concatenate(NULL, foundname, suffix, workspace); - if (result != ISC_R_SUCCESS) - return (ISC_FALSE); - prefixlen = namelabels - foundlabels; - dns_name_init(&tmpprefix, NULL); - dns_name_init(&tmpsuffix, NULL); - if (prefixlen != 0) { - dns_name_getlabelsequence(name, 0, prefixlen, &tmpprefix); - } - INSIST(namebits > foundbits); - bits = namebits - foundbits; - j = 0; - memset(buf, 0, sizeof buf); - INSIST((bits / 8 + 1) < sizeof buf); - /* - * Copy least significant bits. - */ - while (j < bits) { - bit = dns_label_getbit(&namelabel, foundbits + j); - if (bit) - buf[2 + j / 8] |= (1 << (7 - (j % 8))); - j++; - } - buf[0] = DNS_LABELTYPE_BITSTRING; - buf[1] = j; - region.base = buf; - region.length = 2 + (j + 7) / 8; - dns_name_fromregion(&tmpsuffix, ®ion); - result = dns_name_concatenate(&tmpprefix, &tmpsuffix, prefix, - workspace); - if (result != ISC_R_SUCCESS) - return (ISC_FALSE); - *offset = *data; - return (ISC_TRUE); -} diff --git a/lib/dns/config/confparser.y b/lib/dns/config/confparser.y index 95e80faa..dfef5f2b 100644 --- a/lib/dns/config/confparser.y +++ b/lib/dns/config/confparser.y @@ -33,7 +33,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: confparser.y.dirty,v 1.44 2000/12/20 03:36:19 marka Exp $ */ +/* $Id: confparser.y.dirty,v 1.44.2.1 2001/01/05 23:44:56 gson Exp $ */ #include <config.h> @@ -113,9 +113,12 @@ static isc_lexspecials_t specials; /* * XXXJAB The #define for the default OMAPI port is not available * to us, so we make our own. + * + * XXXBEW Same goes for the default LWRES port. */ #define OMAPI_DEFAULT_PORT 953 +#define LWRES_DEFAULT_PORT 921 #define CONF_MAX_IDENT 1024 @@ -157,6 +160,8 @@ static dns_peerlist_t *currentpeerlist(dns_c_ctx_t *cfg, isc_boolean_t createIfNeeded); static isc_boolean_t keydefinedinscope(dns_c_ctx_t *cfg, const char *name); +static void replace_zero_ports(dns_c_iplist_t *list, + in_port_t val); @@ -1258,6 +1263,7 @@ option: /* Empty */ } | L_ALSO_NOTIFY port_ip_list { + replace_zero_ports($2, default_port); tmpres = dns_c_ctx_setalsonotify(currcfg, $2); dns_c_iplist_detach(&$2); @@ -1999,16 +2005,9 @@ port_ip_list: maybe_zero_port L_LBRACE ip_and_port_list L_RBRACE { in_port_t port = $1; dns_c_iplist_t *list = $3; - unsigned int i; - - if (port == 0) - port = default_port; - for (i = 0 ; i < list->nextidx ; i++) { - if (isc_sockaddr_getport(&list->ips[i]) == 0) { - isc_sockaddr_setport(&list->ips[i], port); - } - } + if (port != 0) + replace_zero_ports(list, port); $$ = list; }; @@ -4486,6 +4485,8 @@ view_option: L_FORWARD zone_forward_opt { dns_c_view_t *view = dns_c_ctx_getcurrview(currcfg); + replace_zero_ports($2, default_port); + INSIST(view != NULL); tmpres = dns_c_view_setalsonotify(view, $2); @@ -5062,6 +5063,8 @@ zone_option: L_FILE L_QSTRING INSIST(zone != NULL); + replace_zero_ports($2, default_port); + tmpres = dns_c_zone_setmasterips(zone, $2, ISC_FALSE); if (tmpres == ISC_R_EXISTS) { parser_error(ISC_FALSE, @@ -5653,6 +5656,8 @@ zone_option: L_FILE L_QSTRING INSIST(zone != NULL); + replace_zero_ports($2, default_port); + tmpres = dns_c_zone_setalsonotify(zone, $2, ISC_FALSE); if (tmpres == ISC_R_EXISTS) { parser_error(ISC_FALSE, @@ -5963,6 +5968,9 @@ lwres_options_list: lwres_option L_EOS lwres_option: L_LISTEN_ON port_ip_list { dns_c_lwres_t *lwres; + + replace_zero_ports($2, LWRES_DEFAULT_PORT); + lwres = ISC_LIST_TAIL(currcfg->lwres->lwreslist); tmpres = dns_c_lwres_setlistenon(lwres, $2); dns_c_iplist_detach(&$2); @@ -7048,3 +7056,13 @@ keydefinedinscope(dns_c_ctx_t *cfg, const char *name) return (rval); } + +static void +replace_zero_ports(dns_c_iplist_t *list, in_port_t val) { + unsigned int i; + + for (i = 0 ; i < list->nextidx ; i++) { + if (isc_sockaddr_getport(&list->ips[i]) == 0) + isc_sockaddr_setport(&list->ips[i], val); + } +} diff --git a/lib/dns/include/dns/compress.h b/lib/dns/include/dns/compress.h index c466544c..b65f1789 100644 --- a/lib/dns/include/dns/compress.h +++ b/lib/dns/include/dns/compress.h @@ -15,12 +15,13 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: compress.h,v 1.20 2000/12/28 00:42:56 bwelling Exp $ */ +/* $Id: compress.h,v 1.20.2.1 2001/01/06 01:33:34 gson Exp $ */ #ifndef DNS_COMPRESS_H #define DNS_COMPRESS_H 1 #include <isc/lang.h> +#include <isc/region.h> #include <dns/types.h> @@ -28,28 +29,34 @@ ISC_LANG_BEGINDECLS #define DNS_COMPRESS_NONE 0x00 /* no compression */ #define DNS_COMPRESS_GLOBAL14 0x01 /* "normal" compression. */ -#define DNS_COMPRESS_GLOBAL 0x01 /* all global comp. */ -/* - * Synonymous with DNS_COMPRESS_GLOBAL. A genuine difference existed when - * local compression was an IETF draft, but that draft has been retired without - * becoming a standard. Numerous bits of code referred to DNS_COMPRESS_ALL - * already, and rather than change them all, the DNS_COMPRESS_ALL definition - * was left in, but no longer refers to local compression. - */ -#define DNS_COMPRESS_ALL 0x03 /* all compression. */ +#define DNS_COMPRESS_ALL 0x01 /* all compression. */ /* * Direct manipulation of the structures is strongly discouraged. */ +#define DNS_COMPRESS_TABLESIZE 64 +#define DNS_COMPRESS_INITIALNODES 16 + +typedef struct dns_compressnode dns_compressnode_t; + +struct dns_compressnode { + isc_region_t r; + isc_uint16_t offset; + isc_uint16_t count; + dns_compressnode_t *next; +}; + struct dns_compress { - unsigned int magic; /* Magic number. */ - unsigned int allowed; /* Allowed methods. */ - unsigned int rdata; /* Start of local rdata. */ - isc_boolean_t global16; /* 16 bit offsets allowed. */ - int edns; /* Edns version or -1. */ - dns_rbt_t *global; /* Global RBT. */ - isc_mem_t *mctx; /* Memeory context. */ + unsigned int magic; /* Magic number. */ + unsigned int allowed; /* Allowed methods. */ + int edns; /* Edns version or -1. */ + /* Global compression table. */ + dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE]; + /* Preallocated nodes for the table. */ + dns_compressnode_t initialnodes[DNS_COMPRESS_INITIALNODES]; + isc_uint16_t count; /* Number of nodes. */ + isc_mem_t *mctx; /* Memory context. */ }; typedef enum { @@ -61,7 +68,6 @@ typedef enum { struct dns_decompress { unsigned int magic; /* Magic number. */ unsigned int allowed; /* Allowed methods. */ - unsigned int rdata; /* Start of local rdata. */ int edns; /* Edns version or -1. */ dns_decompresstype_t type; /* Strict checking */ }; @@ -73,9 +79,9 @@ dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx); * * Requires: * 'cctx' is a valid dns_compress_t structure. - * 'mctx' is a initalised memory context. + * 'mctx' is an initialized memory context. * Ensures: - * cctx->global is initalised. + * cctx->global is initialized. * * Returns: * ISC_R_SUCCESS @@ -87,10 +93,9 @@ dns_compress_invalidate(dns_compress_t *cctx); /* * Invalidate the compression structure pointed to by cctx. - * Destroys 'cctx->glocal' and 'cctx->local' RBT. * * Requires: - * 'cctx' to be initalised. + * 'cctx' to be initialized. */ void @@ -100,7 +105,7 @@ dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed); * Sets allowed compression methods. * * Requires: - * 'cctx' to be initalised. + * 'cctx' to be initialized. */ unsigned int @@ -110,7 +115,7 @@ dns_compress_getmethods(dns_compress_t *cctx); * Gets allowed compression methods. * * Requires: - * 'cctx' to be initalised. + * 'cctx' to be initialized. * * Returns: * allowed compression bitmap. @@ -123,7 +128,7 @@ dns_compress_getedns(dns_compress_t *cctx); * Gets edns value. * * Requires: - * 'cctx' to be initalised. + * 'cctx' to be initialized. * * Returns: * -1 .. 255 @@ -132,19 +137,16 @@ dns_compress_getedns(dns_compress_t *cctx); isc_boolean_t dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, dns_name_t *prefix, dns_name_t *suffix, - isc_uint16_t *offset, isc_buffer_t *workspace); + isc_uint16_t *offset); /* - * Finds longest possible match of 'name' in the global compression - * RBT. Workspace needs to be large enough to hold 'name' when split - * in two (length->name + 3). + * Finds longest possible match of 'name' in the global compression table. * * Requires: - * 'cctx' to be initalised. + * 'cctx' to be initialized. * 'name' to be a absolute name. - * 'prefix' to be initalised. - * 'suffix' to be initalised. + * 'prefix' to be initialized. + * 'suffix' to be initialized. * 'offset' to point it a isc_uint16_t. - * 'workspace' to be initalised. * * Ensures: * 'prefix', 'suffix' and 'offset' are valid if ISC_TRUE is @@ -155,27 +157,26 @@ dns_compress_findglobal(dns_compress_t *cctx, dns_name_t *name, */ void -dns_compress_add(dns_compress_t *cctx, dns_name_t *prefix, - dns_name_t *suffix, isc_uint16_t offset); +dns_compress_add(dns_compress_t *cctx, dns_name_t *name, dns_name_t *prefix, + isc_uint16_t offset); /* - * Add compression pointers for labels in prefix to RBT's. - * If 'prefix' is absolute 'suffix' must be NULL otherwise - * suffix must be absolute. + * Add compression pointers for name to the compression table, + * not replacing existing pointers. * * Requires: - * 'cctx' initalised - * 'prefix' to be initalised - * 'suffix' to be initalised or NULL + * 'cctx' initialized + * 'name' must be initialized and absolute, and must remain + * valid until the message compression is complete. */ void dns_compress_rollback(dns_compress_t *cctx, isc_uint16_t offset); /* - * Remove any compression pointers from global RBT >= offset. + * Remove any compression pointers from global table >= offset. * * Requires: - * 'cctx' is initalised. + * 'cctx' is initialized. */ void @@ -197,7 +198,7 @@ dns_decompress_invalidate(dns_decompress_t *dctx); * Invalidates 'dctx'. * * Requires: - * 'dctx' to be initalised + * 'dctx' to be initialized */ void @@ -207,7 +208,7 @@ dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed); * Sets 'dctx->allowed' to 'allowed'. * * Requires: - * 'dctx' to be initalised + * 'dctx' to be initialized */ unsigned int @@ -217,7 +218,7 @@ dns_decompress_getmethods(dns_decompress_t *dctx); * Returns 'dctx->allowed' * * Requires: - * 'dctx' to be initalised + * 'dctx' to be initialized */ int @@ -227,7 +228,7 @@ dns_decompress_edns(dns_decompress_t *dctx); * Returns 'dctx->edns' * * Requires: - * 'dctx' to be initalised + * 'dctx' to be initialized */ dns_decompresstype_t @@ -237,7 +238,7 @@ dns_decompress_type(dns_decompress_t *dctx); * Returns 'dctx->type' * * Requires: - * 'dctx' to be initalised + * 'dctx' to be initialized */ ISC_LANG_ENDDECLS diff --git a/lib/dns/message.c b/lib/dns/message.c index fe932273..042a453c 100644 --- a/lib/dns/message.c +++ b/lib/dns/message.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: message.c,v 1.164 2000/12/11 19:24:13 bwelling Exp $ */ +/* $Id: message.c,v 1.164.2.1 2001/01/05 23:50:16 gson Exp $ */ /*** *** Imports @@ -1771,10 +1771,10 @@ dns_message_rendersection(dns_message_t *msg, dns_section_t sectionid, } /* - * If we have rendered pending data, ensure - * that the AD bit is not set. + * If we have rendered non-validated data, + * ensure that the AD bit is not set. */ - if (rdataset->trust == dns_trust_pending && + if (rdataset->trust != dns_trust_secure && (sectionid == DNS_SECTION_ANSWER || sectionid == DNS_SECTION_AUTHORITY)) msg->flags &= ~DNS_MESSAGEFLAG_AD; diff --git a/lib/dns/name.c b/lib/dns/name.c index 55c2e130..2ed8e899 100644 --- a/lib/dns/name.c +++ b/lib/dns/name.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: name.c,v 1.110 2000/12/28 00:42:55 bwelling Exp $ */ +/* $Id: name.c,v 1.110.2.1 2001/01/06 01:33:32 gson Exp $ */ #include <config.h> @@ -2385,8 +2385,6 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) { dns_name_t gp, gs; isc_boolean_t gf; isc_uint16_t go; - unsigned char gb[257]; - isc_buffer_t gws; dns_offsets_t po, so, clo; dns_name_t clname; @@ -2409,14 +2407,13 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) { } dns_name_init(&gp, po); dns_name_init(&gs, so); - isc_buffer_init(&gws, gb, sizeof (gb)); offset = target->used; /*XXX*/ methods = dns_compress_getmethods(cctx); - if ((methods & DNS_COMPRESS_GLOBAL) != 0) - gf = dns_compress_findglobal(cctx, name, &gp, &gs, &go, &gws); + if ((methods & DNS_COMPRESS_GLOBAL14) != 0) + gf = dns_compress_findglobal(cctx, name, &gp, &gs, &go); else gf = ISC_FALSE; @@ -2444,14 +2441,14 @@ dns_name_towire(dns_name_t *name, dns_compress_t *cctx, isc_buffer_t *target) { return (ISC_R_NOSPACE); isc_buffer_putuint16(target, go); if (gp.length != 0) - dns_compress_add(cctx, &gp, &gs, offset); + dns_compress_add(cctx, name, &gp, offset); } else { if (target->length - target->used < name->length) return (ISC_R_NOSPACE); (void)memcpy((unsigned char *)target->base + target->used, name->ndata, (size_t)name->length); isc_buffer_add(target, name->length); - dns_compress_add(cctx, name, NULL, offset); + dns_compress_add(cctx, name, name, offset); } return (ISC_R_SUCCESS); } diff --git a/lib/dns/request.c b/lib/dns/request.c index 78841326..c88f4d60 100644 --- a/lib/dns/request.c +++ b/lib/dns/request.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: request.c,v 1.45 2000/12/22 19:39:01 gson Exp $ */ +/* $Id: request.c,v 1.45.2.2 2001/01/03 23:34:54 gson Exp $ */ #include <config.h> @@ -87,13 +87,16 @@ struct dns_request { }; #define DNS_REQUEST_F_CONNECTING 0x0001 -#define DNS_REQUEST_F_CANCELED 0x0002 -#define DNS_REQUEST_F_TIMEDOUT 0x0004 /* cancelled due to a timeout */ -#define DNS_REQUEST_F_TCP 0x0008 /* This request used TCP */ +#define DNS_REQUEST_F_SENDING 0x0002 +#define DNS_REQUEST_F_CANCELED 0x0004 +#define DNS_REQUEST_F_TIMEDOUT 0x0008 /* cancelled due to a timeout */ +#define DNS_REQUEST_F_TCP 0x0010 /* This request used TCP */ #define DNS_REQUEST_CANCELED(r) \ (((r)->flags & DNS_REQUEST_F_CANCELED) != 0) #define DNS_REQUEST_CONNECTING(r) \ (((r)->flags & DNS_REQUEST_F_CONNECTING) != 0) +#define DNS_REQUEST_SENDING(r) \ + (((r)->flags & DNS_REQUEST_F_SENDING) != 0) #define DNS_REQUEST_TIMEDOUT(r) \ (((r)->flags & DNS_REQUEST_F_TIMEDOUT) != 0) @@ -416,14 +419,18 @@ static inline isc_result_t req_send(dns_request_t *request, isc_task_t *task, isc_sockaddr_t *address) { isc_region_t r; isc_socket_t *socket; + isc_result_t result; req_log(ISC_LOG_DEBUG(3), "req_send: request %p", request); REQUIRE(VALID_REQUEST(request)); socket = dns_dispatch_getsocket(request->dispatch); isc_buffer_usedregion(request->query, &r); - return (isc_socket_sendto(socket, &r, task, req_senddone, - request, address, NULL)); + result = isc_socket_sendto(socket, &r, task, req_senddone, + request, address, NULL); + if (result == ISC_R_SUCCESS) + request->flags |= DNS_REQUEST_F_SENDING; + return (result); } isc_result_t @@ -1107,7 +1114,8 @@ dns_request_cancel(dns_request_t *request) { LOCK(&request->requestmgr->locks[request->hash]); if (!DNS_REQUEST_CANCELED(request)) { req_cancel(request); - if (!DNS_REQUEST_CONNECTING(request)) + if (!DNS_REQUEST_CONNECTING(request) && + !DNS_REQUEST_SENDING(request)) req_sendevent(request, ISC_R_CANCELED); } UNLOCK(&request->requestmgr->locks[request->hash]); @@ -1158,6 +1166,7 @@ dns_request_destroy(dns_request_t **requestp) { ISC_LIST_UNLINK(request->requestmgr->requests, request, link); UNLOCK(&request->requestmgr->lock); INSIST(!DNS_REQUEST_CONNECTING(request)); + INSIST(!DNS_REQUEST_SENDING(request)); UNLOCK(&request->requestmgr->locks[request->hash]); req_destroy(request); @@ -1198,7 +1207,7 @@ req_connected(isc_task_t *task, isc_event_t *event) { if (result == ISC_R_SUCCESS) result = req_send(request, task, NULL); - if (sevent->result != ISC_R_SUCCESS) { + if (result != ISC_R_SUCCESS) { req_cancel(request); req_sendevent(request, ISC_R_CANCELED); } @@ -1214,13 +1223,28 @@ req_senddone(isc_task_t *task, isc_event_t *event) { REQUIRE(event->ev_type == ISC_SOCKEVENT_SENDDONE); REQUIRE(VALID_REQUEST(request)); + REQUIRE(DNS_REQUEST_SENDING(request)); req_log(ISC_LOG_DEBUG(3), "req_senddone: request %p", request); UNUSED(task); - if (sevent->result != ISC_R_SUCCESS) - dns_request_cancel(request); + LOCK(&request->requestmgr->locks[request->hash]); + request->flags &= ~DNS_REQUEST_F_SENDING; + + if (DNS_REQUEST_CANCELED(request)) { + /* + * Send delayed event. + */ + if (DNS_REQUEST_TIMEDOUT(request)) + req_sendevent(request, ISC_R_TIMEDOUT); + else + req_sendevent(request, ISC_R_CANCELED); + } else if (sevent->result != ISC_R_SUCCESS) { + req_cancel(request); + req_sendevent(request, ISC_R_CANCELED); + } + UNLOCK(&request->requestmgr->locks[request->hash]); isc_event_free(&event); } @@ -1281,7 +1305,8 @@ req_timeout(isc_task_t *task, isc_event_t *event) { LOCK(&request->requestmgr->locks[request->hash]); request->flags |= DNS_REQUEST_F_TIMEDOUT; req_cancel(request); - if (!DNS_REQUEST_CONNECTING(request)) + if (!DNS_REQUEST_CONNECTING(request) && + !DNS_REQUEST_SENDING(request)) req_sendevent(request, ISC_R_TIMEDOUT); UNLOCK(&request->requestmgr->locks[request->hash]); isc_event_free(&event); @@ -1356,6 +1381,10 @@ req_cancel(dns_request_t *request) { socket = dns_dispatch_getsocket(request->dispatch); isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_CONNECT); } + if (DNS_REQUEST_SENDING(request)) { + socket = dns_dispatch_getsocket(request->dispatch); + isc_socket_cancel(socket, NULL, ISC_SOCKCANCEL_SEND); + } dns_dispatch_detach(&request->dispatch); } diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 75308b4e..d4167c0f 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: resolver.c,v 1.187 2000/12/20 23:18:37 gson Exp $ */ +/* $Id: resolver.c,v 1.187.2.2 2001/01/05 22:18:28 bwelling Exp $ */ #include <config.h> @@ -152,6 +152,7 @@ struct fetchctx { /* Locked by appropriate bucket lock. */ fetchstate state; isc_boolean_t want_shutdown; + isc_boolean_t cloned; unsigned int references; isc_event_t control_event; ISC_LINK(struct fetchctx) link; @@ -173,19 +174,26 @@ struct fetchctx { dns_fwdpolicy_t fwdpolicy; isc_sockaddrlist_t bad; ISC_LIST(dns_validator_t) validators; + /* - * # of events we're waiting for. + * The number of events we're waiting for. */ unsigned int pending; + /* - * # of times we have started from the beginning - * of the name server set. + * The number of times we've "restarted" the current + * nameserver set. This acts as a failsafe to prevent + * us from pounding constantly on a particular set of + * servers that, for whatever reason, are not giving + * us useful responses, but are responding in such a + * way that they are not marked "bad". */ unsigned int restarts; + /* - * # of timeouts that have occurred since we last - * successfully received a response packet. This - * is used for EDNS0 black hole detectino. + * The number of timeouts that have occurred since we + * last successfully received a response packet. This + * is used for EDNS0 black hole detection. */ unsigned int timeouts; }; @@ -2048,6 +2056,7 @@ fctx_create(dns_resolver_t *res, dns_name_t *name, dns_rdatatype_t type, fctx->bucketnum = bucketnum; fctx->state = fetchstate_init; fctx->want_shutdown = ISC_FALSE; + fctx->cloned = ISC_FALSE; ISC_LIST_INIT(fctx->queries); ISC_LIST_INIT(fctx->finds); ISC_LIST_INIT(fctx->forwaddrs); @@ -2302,6 +2311,7 @@ clone_results(fetchctx_t *fctx) { * Caller must be holding the appropriate lock. */ + fctx->cloned = ISC_TRUE; hevent = ISC_LIST_HEAD(fctx->events); if (hevent == NULL) return; @@ -4213,6 +4223,11 @@ resquery_response(isc_task_t *task, isc_event_t *event) { */ get_nameservers = ISC_TRUE; keep_trying = ISC_TRUE; + /* + * We have a new set of name servers, and it + * has not experienced any restarts yet. + */ + fctx->restarts = 0; result = ISC_R_SUCCESS; } else if (result != ISC_R_SUCCESS) { /* @@ -4867,7 +4882,16 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, } } - if (fctx == NULL || fctx->state == fetchstate_done) { + /* + * If we didn't have a fetch, would attach to a done fetch, this + * fetch has already cloned its results, or if the fetch has gone + * "idle" (no one was interested in it), we need to start a new + * fetch instead of joining with the existing one. + */ + if (fctx == NULL || + fctx->state == fetchstate_done || + fctx->cloned || + ISC_LIST_EMPTY(fctx->events)) { fctx = NULL; result = fctx_create(res, name, type, domain, nameservers, options, bucketnum, &fctx); @@ -4875,6 +4899,7 @@ dns_resolver_createfetch(dns_resolver_t *res, dns_name_t *name, goto unlock; new_fctx = ISC_TRUE; } + result = fctx_join(fctx, task, action, arg, rdataset, sigrdataset, fetch); if (new_fctx) { diff --git a/lib/dns/zone.c b/lib/dns/zone.c index c0eebf5c..1622ae3d 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: zone.c,v 1.283 2000/12/28 01:29:06 marka Exp $ */ +/* $Id: zone.c,v 1.283.2.1 2000/12/29 19:13:56 gson Exp $ */ #include <config.h> @@ -247,6 +247,7 @@ struct dns_zone { #define DNS_ZONEFLG_NOREFRESH 0x00010000U #define DNS_ZONEFLG_DIALNOTIFY 0x00020000U #define DNS_ZONEFLG_DIALREFRESH 0x00040000U +#define DNS_ZONEFLG_SHUTDOWN 0x00080000U #define DNS_ZONE_OPTION(z,o) (((z)->options & (o)) != 0) @@ -1250,17 +1251,21 @@ zone_postload(dns_zone_t *zone, dns_db_t *db, isc_time_t loadtime, return (result); } -static void +static isc_boolean_t exit_check(dns_zone_t *zone) { - if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING) && + + REQUIRE(LOCKED_ZONE(zone)); + + if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) { /* - * DNS_ZONEFLG_EXITING can only be set if erefs == 0. + * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. */ INSIST(zone->erefs == 0); - zone_free(zone); + return (ISC_TRUE); } + return (ISC_FALSE); } static isc_result_t @@ -1517,6 +1522,7 @@ zone_idetach(dns_zone_t **zonep) { void dns_zone_idetach(dns_zone_t **zonep) { dns_zone_t *zone; + isc_boolean_t free_needed; REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); zone = *zonep; @@ -1527,8 +1533,10 @@ dns_zone_idetach(dns_zone_t **zonep) { zone->irefs--; zone_log(zone, "dns_zone_idetach", ISC_LOG_DEBUG(10), "eref = %d, irefs = %d", zone->erefs, zone->irefs); + free_needed = exit_check(zone); UNLOCK_ZONE(zone); - exit_check(zone); + if (free_needed) + zone_free(zone); } isc_mem_t * @@ -3518,12 +3526,17 @@ static void zone_shutdown(isc_task_t *task, isc_event_t *event) { dns_zone_t *zone = (dns_zone_t *) event->ev_arg; isc_result_t result; + isc_boolean_t free_needed; UNUSED(task); REQUIRE(DNS_ZONE_VALID(zone)); INSIST(event->ev_type == DNS_EVENT_ZONECONTROL); INSIST(zone->erefs == 0); zone_log(zone, "zone_shutdown", ISC_LOG_DEBUG(3), "shutting down"); + + /* + * Stop things being restarted after we cancel them below. + */ LOCK_ZONE(zone); DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_EXITING); UNLOCK_ZONE(zone); @@ -3532,29 +3545,27 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { * If we were waiting for xfrin quota, step out of * the queue. */ + RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); if (zone->statelist == &zone->zmgr->waiting_for_xfrin) { - RWLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); ISC_LIST_UNLINK(zone->zmgr->waiting_for_xfrin, zone, statelink); - RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); zone->statelist = NULL; } + RWUNLOCK(&zone->zmgr->rwlock, isc_rwlocktype_write); + + LOCK_ZONE(zone); if (zone->xfr != NULL) dns_xfrin_shutdown(zone->xfr); - LOCK_ZONE(zone); if (zone->request != NULL) { dns_request_cancel(zone->request); } - UNLOCK_ZONE(zone); if (zone->readio != NULL) zonemgr_cancelio(zone->readio); - LOCK_ZONE(zone); notify_cancel(zone); - UNLOCK_ZONE(zone); if (zone->timer != NULL) { result = isc_timer_reset(zone->timer, isc_timertype_inactive, @@ -3565,7 +3576,16 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { if (zone->view != NULL) dns_view_weakdetach(&zone->view); - exit_check(zone); + /* + * We have now canceled everything set the flag to allow exit_check() + * to succeed. We must not unlock between setting this flag and + * calling exit_check(). + */ + DNS_ZONE_SETFLAG(zone, DNS_ZONEFLG_SHUTDOWN); + free_needed = exit_check(zone); + UNLOCK_ZONE(zone); + if (free_needed) + zone_free(zone); } static void diff --git a/lib/isc/unix/include/isc/net.h b/lib/isc/unix/include/isc/net.h index b01e9ceb..3e6a07b2 100644 --- a/lib/isc/unix/include/isc/net.h +++ b/lib/isc/unix/include/isc/net.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: net.h,v 1.24 2000/12/08 00:55:32 tale Exp $ */ +/* $Id: net.h,v 1.24.4.1 2001/01/03 20:37:58 gson Exp $ */ #ifndef ISC_NET_H #define ISC_NET_H 1 @@ -118,20 +118,20 @@ extern const struct in6_addr isc_net_in6addrany; * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions. */ #ifdef ISC_PLATFORM_FIXIN6ISADDR -#define IN6_IS_ADDR_GEOGRAPHIC +#undef IN6_IS_ADDR_GEOGRAPHIC #define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80) -#define IN6_IS_ADDR_IPX -#define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04) -#define IN6_IS_ADDR_LINKLOCAL -#define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE) -#define IN6_IS_ADDR_MULTICAST -#define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF) -#define IN6_IS_ADDR_NSAP -#define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02) -#define IN6_IS_ADDR_PROVIDER -#define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40) -#define IN6_IS_ADDR_SITELOCAL -#define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE) +#undef IN6_IS_ADDR_IPX +#define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04) +#undef IN6_IS_ADDR_LINKLOCAL +#define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE) +#undef IN6_IS_ADDR_MULTICAST +#define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF) +#undef IN6_IS_ADDR_NSAP +#define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02) +#undef IN6_IS_ADDR_PROVIDER +#define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40) +#undef IN6_IS_ADDR_SITELOCAL +#define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE) #endif /* ISC_PLATFORM_FIXIN6ISADDR */ /* diff --git a/lib/tests/t_api.c b/lib/tests/t_api.c index 6c6997b4..6ad86b7f 100644 --- a/lib/tests/t_api.c +++ b/lib/tests/t_api.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: t_api.c,v 1.45 2000/12/28 00:42:59 bwelling Exp $ */ +/* $Id: t_api.c,v 1.45.2.1 2001/01/06 00:11:23 gson Exp $ */ #include <config.h> @@ -654,7 +654,6 @@ struct dc_method_map { { DNS_COMPRESS_NONE, "DNS_COMPRESS_NONE" }, { DNS_COMPRESS_GLOBAL14, "DNS_COMPRESS_GLOBAL14" }, - { DNS_COMPRESS_GLOBAL, "DNS_COMPRESS_GLOBAL" }, { DNS_COMPRESS_ALL, "DNS_COMPRESS_ALL" }, { 0, NULL } }; |