"Fossies" - the Fresh Open Source Software Archive

Member "bind-9.17.5/lib/dns/compress.c" (4 Sep 2020, 14757 Bytes) of package /linux/misc/dns/bind9/9.17.5/bind-9.17.5.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "compress.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
    3  *
    4  * This Source Code Form is subject to the terms of the Mozilla Public
    5  * License, v. 2.0. If a copy of the MPL was not distributed with this
    6  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
    7  *
    8  * See the COPYRIGHT file distributed with this work for additional
    9  * information regarding copyright ownership.
   10  */
   11 
   12 /*! \file */
   13 
   14 #define DNS_NAME_USEINLINE 1
   15 
   16 #include <inttypes.h>
   17 #include <stdbool.h>
   18 
   19 #include <isc/mem.h>
   20 #include <isc/string.h>
   21 #include <isc/util.h>
   22 
   23 #include <dns/compress.h>
   24 #include <dns/fixedname.h>
   25 #include <dns/rbt.h>
   26 #include <dns/result.h>
   27 
   28 #define CCTX_MAGIC    ISC_MAGIC('C', 'C', 'T', 'X')
   29 #define VALID_CCTX(x) ISC_MAGIC_VALID(x, CCTX_MAGIC)
   30 
   31 #define DCTX_MAGIC    ISC_MAGIC('D', 'C', 'T', 'X')
   32 #define VALID_DCTX(x) ISC_MAGIC_VALID(x, DCTX_MAGIC)
   33 
   34 static unsigned char maptolower[] = {
   35     0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b,
   36     0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
   37     0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23,
   38     0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
   39     0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b,
   40     0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
   41     0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73,
   42     0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
   43     0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b,
   44     0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
   45     0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83,
   46     0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
   47     0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b,
   48     0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
   49     0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3,
   50     0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
   51     0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb,
   52     0xcc, 0xcd, 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
   53     0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3,
   54     0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
   55     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xfb,
   56     0xfc, 0xfd, 0xfe, 0xff
   57 };
   58 
   59 /*
   60  * The tableindex array below is of size 256, one entry for each
   61  * unsigned char value. The tableindex array elements are dependent on
   62  * DNS_COMPRESS_TABLESIZE. The table was created using the following
   63  * function.
   64  *
   65  * static void
   66  * gentable(unsigned char *table) {
   67  *         unsigned int i;
   68  *         const unsigned int left = DNS_COMPRESS_TABLESIZE - 38;
   69  *         long r;
   70  *
   71  *         for (i = 0; i < 26; i++) {
   72  *                 table['A' + i] = i;
   73  *                 table['a' + i] = i;
   74  *         }
   75  *
   76  *         for (i = 0; i <= 9; i++)
   77  *                 table['0' + i] = i + 26;
   78  *
   79  *         table['-'] = 36;
   80  *         table['_'] = 37;
   81  *
   82  *         for (i = 0; i < 256; i++) {
   83  *                 if ((i >= 'a' && i <= 'z') ||
   84  *                     (i >= 'A' && i <= 'Z') ||
   85  *                     (i >= '0' && i <= '9') ||
   86  *                     (i == '-') ||
   87  *                     (i == '_'))
   88  *                         continue;
   89  *                 r = random() % left;
   90  *                 table[i] = 38 + r;
   91  *         }
   92  * }
   93  */
   94 static unsigned char tableindex[256] = {
   95     0x3e, 0x3e, 0x33, 0x2d, 0x30, 0x38, 0x31, 0x3c, 0x2b, 0x33, 0x30, 0x3f,
   96     0x2d, 0x3c, 0x36, 0x3a, 0x28, 0x2c, 0x2a, 0x37, 0x3d, 0x34, 0x35, 0x2d,
   97     0x39, 0x2b, 0x2f, 0x2c, 0x3b, 0x32, 0x2b, 0x39, 0x30, 0x38, 0x28, 0x3c,
   98     0x32, 0x33, 0x39, 0x38, 0x27, 0x2b, 0x39, 0x30, 0x27, 0x24, 0x2f, 0x2b,
   99     0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x3a, 0x29, 0x36,
  100     0x31, 0x3c, 0x35, 0x26, 0x31, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06,
  101     0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12,
  102     0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x3e, 0x3b, 0x39, 0x2f, 0x25,
  103     0x27, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a,
  104     0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16,
  105     0x17, 0x18, 0x19, 0x36, 0x3b, 0x2f, 0x2f, 0x2e, 0x29, 0x33, 0x2a, 0x36,
  106     0x28, 0x3f, 0x2e, 0x29, 0x2c, 0x29, 0x36, 0x2d, 0x32, 0x3d, 0x33, 0x2a,
  107     0x2e, 0x2f, 0x3b, 0x30, 0x3d, 0x39, 0x2b, 0x36, 0x2a, 0x2f, 0x2c, 0x26,
  108     0x3a, 0x37, 0x30, 0x3d, 0x2a, 0x36, 0x33, 0x2c, 0x38, 0x3d, 0x32, 0x3e,
  109     0x26, 0x2a, 0x2c, 0x35, 0x27, 0x39, 0x3b, 0x31, 0x2a, 0x37, 0x3c, 0x27,
  110     0x32, 0x29, 0x39, 0x37, 0x34, 0x3f, 0x39, 0x2e, 0x38, 0x2b, 0x2c, 0x3e,
  111     0x3b, 0x3b, 0x2d, 0x33, 0x3b, 0x3b, 0x32, 0x3d, 0x3f, 0x3a, 0x34, 0x26,
  112     0x35, 0x30, 0x31, 0x39, 0x27, 0x2f, 0x3d, 0x35, 0x35, 0x36, 0x2e, 0x29,
  113     0x38, 0x27, 0x34, 0x32, 0x2c, 0x3c, 0x31, 0x28, 0x37, 0x38, 0x37, 0x34,
  114     0x33, 0x29, 0x32, 0x34, 0x3f, 0x26, 0x34, 0x34, 0x32, 0x27, 0x30, 0x33,
  115     0x33, 0x2d, 0x2b, 0x28, 0x3f, 0x33, 0x2b, 0x39, 0x37, 0x39, 0x2c, 0x3d,
  116     0x35, 0x39, 0x27, 0x2f
  117 };
  118 
  119 /***
  120  ***    Compression
  121  ***/
  122 
  123 isc_result_t
  124 dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) {
  125     REQUIRE(cctx != NULL);
  126     REQUIRE(mctx != NULL); /* See: rdataset.c:towiresorted(). */
  127 
  128     cctx->edns = edns;
  129     cctx->mctx = mctx;
  130     cctx->count = 0;
  131     cctx->allowed = DNS_COMPRESS_ENABLED;
  132     cctx->arena_off = 0;
  133 
  134     memset(&cctx->table[0], 0, sizeof(cctx->table));
  135 
  136     cctx->magic = CCTX_MAGIC;
  137 
  138     return (ISC_R_SUCCESS);
  139 }
  140 
  141 void
  142 dns_compress_invalidate(dns_compress_t *cctx) {
  143     dns_compressnode_t *node;
  144     unsigned int i;
  145 
  146     REQUIRE(VALID_CCTX(cctx));
  147 
  148     for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
  149         while (cctx->table[i] != NULL) {
  150             node = cctx->table[i];
  151             cctx->table[i] = cctx->table[i]->next;
  152             if ((node->offset & 0x8000) != 0) {
  153                 isc_mem_put(cctx->mctx, node->r.base,
  154                         node->r.length);
  155             }
  156             if (node->count < DNS_COMPRESS_INITIALNODES) {
  157                 continue;
  158             }
  159             isc_mem_put(cctx->mctx, node, sizeof(*node));
  160         }
  161     }
  162 
  163     cctx->magic = 0;
  164     cctx->allowed = 0;
  165     cctx->edns = -1;
  166 }
  167 
  168 void
  169 dns_compress_setmethods(dns_compress_t *cctx, unsigned int allowed) {
  170     REQUIRE(VALID_CCTX(cctx));
  171 
  172     cctx->allowed &= ~DNS_COMPRESS_ALL;
  173     cctx->allowed |= (allowed & DNS_COMPRESS_ALL);
  174 }
  175 
  176 unsigned int
  177 dns_compress_getmethods(dns_compress_t *cctx) {
  178     REQUIRE(VALID_CCTX(cctx));
  179     return (cctx->allowed & DNS_COMPRESS_ALL);
  180 }
  181 
  182 void
  183 dns_compress_disable(dns_compress_t *cctx) {
  184     REQUIRE(VALID_CCTX(cctx));
  185     cctx->allowed &= ~DNS_COMPRESS_ENABLED;
  186 }
  187 
  188 void
  189 dns_compress_setsensitive(dns_compress_t *cctx, bool sensitive) {
  190     REQUIRE(VALID_CCTX(cctx));
  191 
  192     if (sensitive) {
  193         cctx->allowed |= DNS_COMPRESS_CASESENSITIVE;
  194     } else {
  195         cctx->allowed &= ~DNS_COMPRESS_CASESENSITIVE;
  196     }
  197 }
  198 
  199 bool
  200 dns_compress_getsensitive(dns_compress_t *cctx) {
  201     REQUIRE(VALID_CCTX(cctx));
  202 
  203     return (cctx->allowed & DNS_COMPRESS_CASESENSITIVE);
  204 }
  205 
  206 int
  207 dns_compress_getedns(dns_compress_t *cctx) {
  208     REQUIRE(VALID_CCTX(cctx));
  209     return (cctx->edns);
  210 }
  211 
  212 /*
  213  * Find the longest match of name in the table.
  214  * If match is found return true. prefix, suffix and offset are updated.
  215  * If no match is found return false.
  216  */
  217 bool
  218 dns_compress_findglobal(dns_compress_t *cctx, const dns_name_t *name,
  219             dns_name_t *prefix, uint16_t *offset) {
  220     dns_name_t tname;
  221     dns_compressnode_t *node = NULL;
  222     unsigned int labels, i, n;
  223     unsigned int numlabels;
  224     unsigned char *p;
  225 
  226     REQUIRE(VALID_CCTX(cctx));
  227     REQUIRE(dns_name_isabsolute(name));
  228     REQUIRE(offset != NULL);
  229 
  230     if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0)) {
  231         return (false);
  232     }
  233 
  234     if (cctx->count == 0) {
  235         return (false);
  236     }
  237 
  238     labels = dns_name_countlabels(name);
  239     INSIST(labels > 0);
  240 
  241     dns_name_init(&tname, NULL);
  242 
  243     numlabels = labels > 3U ? 3U : labels;
  244     p = name->ndata;
  245 
  246     for (n = 0; n < numlabels - 1; n++) {
  247         unsigned char ch, llen;
  248         unsigned int firstoffset, length;
  249 
  250         firstoffset = (unsigned int)(p - name->ndata);
  251         length = name->length - firstoffset;
  252 
  253         /*
  254          * We calculate the table index using the first
  255          * character in the first label of the suffix name.
  256          */
  257         ch = p[1];
  258         i = tableindex[ch];
  259         if (ISC_LIKELY((cctx->allowed & DNS_COMPRESS_CASESENSITIVE) !=
  260                    0)) {
  261             for (node = cctx->table[i]; node != NULL;
  262                  node = node->next) {
  263                 if (ISC_UNLIKELY(node->name.length != length)) {
  264                     continue;
  265                 }
  266 
  267                 if (ISC_LIKELY(memcmp(node->name.ndata, p,
  268                               length) == 0)) {
  269                     goto found;
  270                 }
  271             }
  272         } else {
  273             for (node = cctx->table[i]; node != NULL;
  274                  node = node->next) {
  275                 unsigned int l, count;
  276                 unsigned char c;
  277                 unsigned char *label1, *label2;
  278 
  279                 if (ISC_UNLIKELY(node->name.length != length)) {
  280                     continue;
  281                 }
  282 
  283                 l = labels - n;
  284                 if (ISC_UNLIKELY(node->name.labels != l)) {
  285                     continue;
  286                 }
  287 
  288                 label1 = node->name.ndata;
  289                 label2 = p;
  290                 while (ISC_LIKELY(l-- > 0)) {
  291                     count = *label1++;
  292                     if (count != *label2++) {
  293                         goto cont1;
  294                     }
  295 
  296                     /* no bitstring support */
  297                     INSIST(count <= 63);
  298 
  299                     /* Loop unrolled for performance */
  300                     while (ISC_LIKELY(count > 3)) {
  301                         c = maptolower[label1[0]];
  302                         if (c != maptolower[label2[0]])
  303                         {
  304                             goto cont1;
  305                         }
  306                         c = maptolower[label1[1]];
  307                         if (c != maptolower[label2[1]])
  308                         {
  309                             goto cont1;
  310                         }
  311                         c = maptolower[label1[2]];
  312                         if (c != maptolower[label2[2]])
  313                         {
  314                             goto cont1;
  315                         }
  316                         c = maptolower[label1[3]];
  317                         if (c != maptolower[label2[3]])
  318                         {
  319                             goto cont1;
  320                         }
  321                         count -= 4;
  322                         label1 += 4;
  323                         label2 += 4;
  324                     }
  325                     while (ISC_LIKELY(count-- > 0)) {
  326                         c = maptolower[*label1++];
  327                         if (c != maptolower[*label2++])
  328                         {
  329                             goto cont1;
  330                         }
  331                     }
  332                 }
  333                 break;
  334             cont1:
  335                 continue;
  336             }
  337         }
  338 
  339         if (node != NULL) {
  340             break;
  341         }
  342 
  343         llen = *p;
  344         p += llen + 1;
  345     }
  346 
  347 found:
  348     /*
  349      * If node == NULL, we found no match at all.
  350      */
  351     if (node == NULL) {
  352         return (false);
  353     }
  354 
  355     if (n == 0) {
  356         dns_name_reset(prefix);
  357     } else {
  358         dns_name_getlabelsequence(name, 0, n, prefix);
  359     }
  360 
  361     *offset = (node->offset & 0x7fff);
  362     return (true);
  363 }
  364 
  365 static inline unsigned int
  366 name_length(const dns_name_t *name) {
  367     isc_region_t r;
  368     dns_name_toregion(name, &r);
  369     return (r.length);
  370 }
  371 
  372 void
  373 dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
  374          const dns_name_t *prefix, uint16_t offset) {
  375     dns_name_t tname, xname;
  376     unsigned int start;
  377     unsigned int n;
  378     unsigned int count;
  379     unsigned int i;
  380     dns_compressnode_t *node;
  381     unsigned int length;
  382     unsigned int tlength;
  383     uint16_t toffset;
  384     unsigned char *tmp;
  385     isc_region_t r;
  386     bool allocated = false;
  387 
  388     REQUIRE(VALID_CCTX(cctx));
  389     REQUIRE(dns_name_isabsolute(name));
  390 
  391     if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0)) {
  392         return;
  393     }
  394 
  395     if (offset >= 0x4000) {
  396         return;
  397     }
  398     dns_name_init(&tname, NULL);
  399     dns_name_init(&xname, NULL);
  400 
  401     n = dns_name_countlabels(name);
  402     count = dns_name_countlabels(prefix);
  403     if (dns_name_isabsolute(prefix)) {
  404         count--;
  405     }
  406     if (count == 0) {
  407         return;
  408     }
  409     start = 0;
  410     dns_name_toregion(name, &r);
  411     length = r.length;
  412     if (cctx->arena_off + length < DNS_COMPRESS_ARENA_SIZE) {
  413         tmp = &cctx->arena[cctx->arena_off];
  414         cctx->arena_off += length;
  415     } else {
  416         allocated = true;
  417         tmp = isc_mem_get(cctx->mctx, length);
  418     }
  419     /*
  420      * Copy name data to 'tmp' and make 'r' use 'tmp'.
  421      */
  422     memmove(tmp, r.base, r.length);
  423     r.base = tmp;
  424     dns_name_fromregion(&xname, &r);
  425 
  426     if (count > 2U) {
  427         count = 2U;
  428     }
  429 
  430     while (count > 0) {
  431         unsigned char ch;
  432 
  433         dns_name_getlabelsequence(&xname, start, n, &tname);
  434         /*
  435          * We calculate the table index using the first
  436          * character in the first label of tname.
  437          */
  438         ch = tname.ndata[1];
  439         i = tableindex[ch];
  440         tlength = name_length(&tname);
  441         toffset = (uint16_t)(offset + (length - tlength));
  442         if (toffset >= 0x4000) {
  443             break;
  444         }
  445         /*
  446          * Create a new node and add it.
  447          */
  448         if (cctx->count < DNS_COMPRESS_INITIALNODES) {
  449             node = &cctx->initialnodes[cctx->count];
  450         } else {
  451             node = isc_mem_get(cctx->mctx,
  452                        sizeof(dns_compressnode_t));
  453         }
  454         node->count = cctx->count++;
  455         /*
  456          * 'node->r.base' becomes 'tmp' when start == 0.
  457          * Record this by setting 0x8000 so it can be freed later.
  458          */
  459         if (start == 0 && allocated) {
  460             toffset |= 0x8000;
  461         }
  462         node->offset = toffset;
  463         dns_name_toregion(&tname, &node->r);
  464         dns_name_init(&node->name, NULL);
  465         node->name.length = node->r.length;
  466         node->name.ndata = node->r.base;
  467         node->name.labels = tname.labels;
  468         node->name.attributes = DNS_NAMEATTR_ABSOLUTE;
  469         node->next = cctx->table[i];
  470         cctx->table[i] = node;
  471         start++;
  472         n--;
  473         count--;
  474     }
  475 
  476     if (start == 0) {
  477         if (!allocated) {
  478             cctx->arena_off -= length;
  479         } else {
  480             isc_mem_put(cctx->mctx, tmp, length);
  481         }
  482     }
  483 }
  484 
  485 void
  486 dns_compress_rollback(dns_compress_t *cctx, uint16_t offset) {
  487     unsigned int i;
  488     dns_compressnode_t *node;
  489 
  490     REQUIRE(VALID_CCTX(cctx));
  491 
  492     if (ISC_UNLIKELY((cctx->allowed & DNS_COMPRESS_ENABLED) == 0)) {
  493         return;
  494     }
  495 
  496     for (i = 0; i < DNS_COMPRESS_TABLESIZE; i++) {
  497         node = cctx->table[i];
  498         /*
  499          * This relies on nodes with greater offsets being
  500          * closer to the beginning of the list, and the
  501          * items with the greatest offsets being at the end
  502          * of the initialnodes[] array.
  503          */
  504         while (node != NULL && (node->offset & 0x7fff) >= offset) {
  505             cctx->table[i] = node->next;
  506             if ((node->offset & 0x8000) != 0) {
  507                 isc_mem_put(cctx->mctx, node->r.base,
  508                         node->r.length);
  509             }
  510             if (node->count >= DNS_COMPRESS_INITIALNODES) {
  511                 isc_mem_put(cctx->mctx, node, sizeof(*node));
  512             }
  513             cctx->count--;
  514             node = cctx->table[i];
  515         }
  516     }
  517 }
  518 
  519 /***
  520  ***    Decompression
  521  ***/
  522 
  523 void
  524 dns_decompress_init(dns_decompress_t *dctx, int edns,
  525             dns_decompresstype_t type) {
  526     REQUIRE(dctx != NULL);
  527     REQUIRE(edns >= -1 && edns <= 255);
  528 
  529     dctx->allowed = DNS_COMPRESS_NONE;
  530     dctx->edns = edns;
  531     dctx->type = type;
  532     dctx->magic = DCTX_MAGIC;
  533 }
  534 
  535 void
  536 dns_decompress_invalidate(dns_decompress_t *dctx) {
  537     REQUIRE(VALID_DCTX(dctx));
  538 
  539     dctx->magic = 0;
  540 }
  541 
  542 void
  543 dns_decompress_setmethods(dns_decompress_t *dctx, unsigned int allowed) {
  544     REQUIRE(VALID_DCTX(dctx));
  545 
  546     switch (dctx->type) {
  547     case DNS_DECOMPRESS_ANY:
  548         dctx->allowed = DNS_COMPRESS_ALL;
  549         break;
  550     case DNS_DECOMPRESS_NONE:
  551         dctx->allowed = DNS_COMPRESS_NONE;
  552         break;
  553     case DNS_DECOMPRESS_STRICT:
  554         dctx->allowed = allowed;
  555         break;
  556     }
  557 }
  558 
  559 unsigned int
  560 dns_decompress_getmethods(dns_decompress_t *dctx) {
  561     REQUIRE(VALID_DCTX(dctx));
  562 
  563     return (dctx->allowed);
  564 }
  565 
  566 int
  567 dns_decompress_edns(dns_decompress_t *dctx) {
  568     REQUIRE(VALID_DCTX(dctx));
  569 
  570     return (dctx->edns);
  571 }
  572 
  573 dns_decompresstype_t
  574 dns_decompress_type(dns_decompress_t *dctx) {
  575     REQUIRE(VALID_DCTX(dctx));
  576 
  577     return (dctx->type);
  578 }