cctx->mctx = mctx;
cctx->count = 0;
cctx->allowed = DNS_COMPRESS_ENABLED;
+ cctx->arena_off = 0;
memset(&cctx->table[0], 0, sizeof(cctx->table));
uint16_t toffset;
unsigned char *tmp;
isc_region_t r;
+ bool allocated = false;
REQUIRE(VALID_CCTX(cctx));
REQUIRE(dns_name_isabsolute(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'.
*/
* '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;
}
if (start == 0) {
- isc_mem_put(cctx->mctx, tmp, length);
+ if (!allocated) {
+ cctx->arena_off -= length;
+ } else {
+ isc_mem_put(cctx->mctx, tmp, length);
+ }
}
}
#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;
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. */