]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add an arena to compressctx
authorWitold Kręcicki <wpk@isc.org>
Mon, 3 Feb 2020 10:17:32 +0000 (11:17 +0100)
committerWitold Krecicki <wpk@isc.org>
Wed, 26 Feb 2020 07:57:44 +0000 (07:57 +0000)
lib/dns/compress.c
lib/dns/include/dns/compress.h

index 7ea40b36a64def46f9d7cf3bd2c21b5730649dbf..628da2eb88333b1a4f07b9460a1d1509393afd8c 100644 (file)
@@ -129,6 +129,7 @@ dns_compress_init(dns_compress_t *cctx, int edns, isc_mem_t *mctx) {
        cctx->mctx = mctx;
        cctx->count = 0;
        cctx->allowed = DNS_COMPRESS_ENABLED;
+       cctx->arena_off = 0;
 
        memset(&cctx->table[0], 0, sizeof(cctx->table));
 
@@ -382,6 +383,7 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
        uint16_t toffset;
        unsigned char *tmp;
        isc_region_t r;
+       bool allocated = false;
 
        REQUIRE(VALID_CCTX(cctx));
        REQUIRE(dns_name_isabsolute(name));
@@ -407,7 +409,13 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
        start = 0;
        dns_name_toregion(name, &r);
        length = r.length;
-       tmp = isc_mem_get(cctx->mctx, length);
+       if (cctx->arena_off + length < DNS_COMPRESS_ARENA_SIZE) {
+               tmp = &cctx->arena[cctx->arena_off];
+               cctx->arena_off += length;
+       } else {
+               allocated = true;
+               tmp = isc_mem_get(cctx->mctx, length);
+       }
        /*
         * Copy name data to 'tmp' and make 'r' use 'tmp'.
         */
@@ -448,7 +456,7 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
                 * 'node->r.base' becomes 'tmp' when start == 0.
                 * Record this by setting 0x8000 so it can be freed later.
                 */
-               if (start == 0) {
+               if (start == 0 && allocated) {
                        toffset |= 0x8000;
                }
                node->offset = toffset;
@@ -466,7 +474,11 @@ dns_compress_add(dns_compress_t *cctx, const dns_name_t *name,
        }
 
        if (start == 0) {
-               isc_mem_put(cctx->mctx, tmp, length);
+               if (!allocated) {
+                       cctx->arena_off -= length;
+               } else {
+                       isc_mem_put(cctx->mctx, tmp, length);
+               }
        }
 }
 
index b458bc51cfc2255eee9653b3197a9e5e23e7899e..d09b23231fe0c564dd1a6c19386ec8eea78de935 100644 (file)
@@ -51,7 +51,8 @@ ISC_LANG_BEGINDECLS
 #define DNS_COMPRESS_TABLEBITS   6
 #define DNS_COMPRESS_TABLESIZE   (1U << DNS_COMPRESS_TABLEBITS)
 #define DNS_COMPRESS_TABLEMASK   (DNS_COMPRESS_TABLESIZE - 1)
-#define DNS_COMPRESS_INITIALNODES 16
+#define DNS_COMPRESS_INITIALNODES 24
+#define DNS_COMPRESS_ARENA_SIZE          640
 
 typedef struct dns_compressnode dns_compressnode_t;
 
@@ -69,6 +70,9 @@ struct dns_compress {
        int          edns;    /*%< Edns version or -1. */
        /*% Global compression table. */
        dns_compressnode_t *table[DNS_COMPRESS_TABLESIZE];
+       /*% Preallocated arena for names. */
+       unsigned char arena[DNS_COMPRESS_ARENA_SIZE];
+       off_t         arena_off;
        /*% Preallocated nodes for the table. */
        dns_compressnode_t initialnodes[DNS_COMPRESS_INITIALNODES];
        uint16_t           count; /*%< Number of nodes. */