mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 18:19:42 +00:00
Fuzzing and benchmarking for dns_name_fromwire()
Since this is very sensitive code which has often had security problems in many DNS implementations, it needs a decent amount of validation. This fuzzer ensures that the new code has the same output as the old code, and that it doesn't take longer than a second. The benchmark uses the fuzzer's copy of the old dns_name_fromwire() code to compare a number of scenarios: many compression pointers, many labels, long labels, random data, with/without downcasing.
This commit is contained in:
parent
1c0f607811
commit
04f3000dfc
1
fuzz/.gitignore
vendored
1
fuzz/.gitignore
vendored
@ -4,6 +4,7 @@
|
|||||||
/dns_message_checksig
|
/dns_message_checksig
|
||||||
/dns_message_parse
|
/dns_message_parse
|
||||||
/dns_name_fromtext_target
|
/dns_name_fromtext_target
|
||||||
|
/dns_name_fromwire
|
||||||
/dns_rdata_fromtext
|
/dns_rdata_fromtext
|
||||||
/dns_rdata_fromwire_text
|
/dns_rdata_fromwire_text
|
||||||
/isc_lex_getmastertoken
|
/isc_lex_getmastertoken
|
||||||
|
@ -26,6 +26,7 @@ check_PROGRAMS = \
|
|||||||
dns_message_checksig \
|
dns_message_checksig \
|
||||||
dns_message_parse \
|
dns_message_parse \
|
||||||
dns_name_fromtext_target \
|
dns_name_fromtext_target \
|
||||||
|
dns_name_fromwire \
|
||||||
dns_rdata_fromtext \
|
dns_rdata_fromtext \
|
||||||
dns_rdata_fromwire_text \
|
dns_rdata_fromwire_text \
|
||||||
isc_lex_getmastertoken \
|
isc_lex_getmastertoken \
|
||||||
@ -36,11 +37,17 @@ EXTRA_DIST = \
|
|||||||
dns_message_checksig.in \
|
dns_message_checksig.in \
|
||||||
dns_message_parse.in \
|
dns_message_parse.in \
|
||||||
dns_name_fromtext_target.in \
|
dns_name_fromtext_target.in \
|
||||||
|
dns_name_fromwire.in \
|
||||||
dns_rdata_fromtext.in \
|
dns_rdata_fromtext.in \
|
||||||
dns_rdata_fromwire_text.in \
|
dns_rdata_fromwire_text.in \
|
||||||
isc_lex_getmastertoken.in \
|
isc_lex_getmastertoken.in \
|
||||||
isc_lex_gettoken.in
|
isc_lex_gettoken.in
|
||||||
|
|
||||||
|
dns_name_fromwire_SOURCES = \
|
||||||
|
dns_name_fromwire.c \
|
||||||
|
old.c \
|
||||||
|
old.h
|
||||||
|
|
||||||
TESTS = $(check_PROGRAMS)
|
TESTS = $(check_PROGRAMS)
|
||||||
|
|
||||||
if HAVE_FUZZ_LOG_COMPILER
|
if HAVE_FUZZ_LOG_COMPILER
|
||||||
|
104
fuzz/dns_name_fromwire.c
Normal file
104
fuzz/dns_name_fromwire.c
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <isc/ascii.h>
|
||||||
|
#include <isc/buffer.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include <dns/compress.h>
|
||||||
|
#include <dns/fixedname.h>
|
||||||
|
#include <dns/name.h>
|
||||||
|
|
||||||
|
#include "fuzz.h"
|
||||||
|
#include "old.h"
|
||||||
|
|
||||||
|
bool debug = false;
|
||||||
|
|
||||||
|
int
|
||||||
|
LLVMFuzzerInitialize(int *argc __attribute__((unused)),
|
||||||
|
char ***argv __attribute__((unused))) {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
isc_result_t new_result;
|
||||||
|
isc_result_t old_result;
|
||||||
|
dns_fixedname_t new_fixed;
|
||||||
|
dns_fixedname_t old_fixed;
|
||||||
|
dns_name_t *new_name = dns_fixedname_initname(&new_fixed);
|
||||||
|
dns_name_t *old_name = dns_fixedname_initname(&old_fixed);
|
||||||
|
uint8_t *new_offsets;
|
||||||
|
uint8_t *old_offsets;
|
||||||
|
dns_decompress_t dctx = DNS_DECOMPRESS_PERMITTED;
|
||||||
|
isc_buffer_t new_buf;
|
||||||
|
isc_buffer_t old_buf;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Output buffers may be partially used or undersized.
|
||||||
|
*/
|
||||||
|
if (size > 0) {
|
||||||
|
uint8_t add = *data++;
|
||||||
|
size--;
|
||||||
|
isc_buffer_add(&new_fixed.buffer, add);
|
||||||
|
isc_buffer_add(&old_fixed.buffer, add);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* timeout faster if we hit a pointer loop
|
||||||
|
*/
|
||||||
|
alarm(1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We shift forward by half the input data to make an area
|
||||||
|
* that pointers can refer back to.
|
||||||
|
*/
|
||||||
|
|
||||||
|
isc_buffer_constinit(&new_buf, data, size);
|
||||||
|
isc_buffer_add(&new_buf, size);
|
||||||
|
isc_buffer_setactive(&new_buf, size);
|
||||||
|
isc_buffer_forward(&new_buf, size / 2);
|
||||||
|
new_result = dns_name_fromwire(new_name, &new_buf, dctx, 0, NULL);
|
||||||
|
|
||||||
|
isc_buffer_constinit(&old_buf, data, size);
|
||||||
|
isc_buffer_add(&old_buf, size);
|
||||||
|
isc_buffer_setactive(&old_buf, size);
|
||||||
|
isc_buffer_forward(&old_buf, size / 2);
|
||||||
|
old_result = old_name_fromwire(old_name, &old_buf, dctx, 0, NULL);
|
||||||
|
|
||||||
|
REQUIRE(new_result == old_result);
|
||||||
|
REQUIRE(dns_name_equal(new_name, old_name));
|
||||||
|
REQUIRE(new_name->labels == old_name->labels);
|
||||||
|
|
||||||
|
new_offsets = new_name->offsets;
|
||||||
|
old_offsets = old_name->offsets;
|
||||||
|
REQUIRE(new_offsets != NULL && old_offsets != NULL);
|
||||||
|
REQUIRE(memcmp(new_offsets, old_offsets, old_name->labels) == 0);
|
||||||
|
|
||||||
|
REQUIRE(new_fixed.buffer.current == old_fixed.buffer.current);
|
||||||
|
REQUIRE(new_fixed.buffer.active == old_fixed.buffer.active);
|
||||||
|
REQUIRE(new_fixed.buffer.used == old_fixed.buffer.used);
|
||||||
|
REQUIRE(new_fixed.buffer.length == old_fixed.buffer.length);
|
||||||
|
|
||||||
|
REQUIRE(new_buf.base == old_buf.base);
|
||||||
|
REQUIRE(new_buf.current == old_buf.current);
|
||||||
|
REQUIRE(new_buf.active == old_buf.active);
|
||||||
|
REQUIRE(new_buf.used == old_buf.used);
|
||||||
|
REQUIRE(new_buf.length == old_buf.length);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
<EFBFBD>0
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
<EFBFBD>0<EFBFBD>w
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
0<EFBFBD>
|
Binary file not shown.
@ -0,0 +1,2 @@
|
|||||||
|
<EFBFBD><EFBFBD>
|
||||||
|
<EFBFBD>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
索
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1 @@
|
|||||||
|
*
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
223
fuzz/old.c
Normal file
223
fuzz/old.c
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <isc/ascii.h>
|
||||||
|
#include <isc/buffer.h>
|
||||||
|
#include <isc/result.h>
|
||||||
|
#include <isc/types.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include <dns/compress.h>
|
||||||
|
#include <dns/types.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "old.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* code copied from lib/dns/name.c as of commit
|
||||||
|
* 6967973568fe80b03e1729259f8907ce8792be34
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef enum { fw_start = 0, fw_ordinary, fw_newcurrent } fw_state;
|
||||||
|
|
||||||
|
#define VALID_NAME(n) ISC_MAGIC_VALID(n, DNS_NAME_MAGIC)
|
||||||
|
|
||||||
|
#define INIT_OFFSETS(name, var, default_offsets) \
|
||||||
|
if ((name)->offsets != NULL) \
|
||||||
|
var = (name)->offsets; \
|
||||||
|
else \
|
||||||
|
var = (default_offsets);
|
||||||
|
|
||||||
|
#define MAKE_EMPTY(name) \
|
||||||
|
do { \
|
||||||
|
name->ndata = NULL; \
|
||||||
|
name->length = 0; \
|
||||||
|
name->labels = 0; \
|
||||||
|
name->attributes.absolute = false; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define BINDABLE(name) (!name->attributes.readonly && !name->attributes.dynamic)
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
old_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t dctx,
|
||||||
|
unsigned int options, isc_buffer_t *target) {
|
||||||
|
unsigned char *cdata, *ndata;
|
||||||
|
unsigned int cused; /* Bytes of compressed name data used */
|
||||||
|
unsigned int nused, labels, n, nmax;
|
||||||
|
unsigned int current, new_current, biggest_pointer;
|
||||||
|
bool done;
|
||||||
|
fw_state state = fw_start;
|
||||||
|
unsigned int c;
|
||||||
|
unsigned char *offsets;
|
||||||
|
dns_offsets_t odata;
|
||||||
|
bool downcase;
|
||||||
|
bool seen_pointer;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the possibly-compressed name at source into target,
|
||||||
|
* decompressing it. Loop prevention is performed by checking
|
||||||
|
* the new pointer against biggest_pointer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
REQUIRE(VALID_NAME(name));
|
||||||
|
REQUIRE((target != NULL && ISC_BUFFER_VALID(target)) ||
|
||||||
|
(target == NULL && ISC_BUFFER_VALID(name->buffer)));
|
||||||
|
|
||||||
|
downcase = ((options & DNS_NAME_DOWNCASE) != 0);
|
||||||
|
|
||||||
|
if (target == NULL && name->buffer != NULL) {
|
||||||
|
target = name->buffer;
|
||||||
|
isc_buffer_clear(target);
|
||||||
|
}
|
||||||
|
|
||||||
|
REQUIRE(BINDABLE(name));
|
||||||
|
|
||||||
|
INIT_OFFSETS(name, offsets, odata);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make 'name' empty in case of failure.
|
||||||
|
*/
|
||||||
|
MAKE_EMPTY(name);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize things to make the compiler happy; they're not required.
|
||||||
|
*/
|
||||||
|
n = 0;
|
||||||
|
new_current = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set up.
|
||||||
|
*/
|
||||||
|
labels = 0;
|
||||||
|
done = false;
|
||||||
|
|
||||||
|
ndata = isc_buffer_used(target);
|
||||||
|
nused = 0;
|
||||||
|
seen_pointer = false;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the maximum number of uncompressed target name
|
||||||
|
* bytes we are willing to generate. This is the smaller
|
||||||
|
* of the available target buffer length and the
|
||||||
|
* maximum legal domain name length (255).
|
||||||
|
*/
|
||||||
|
nmax = isc_buffer_availablelength(target);
|
||||||
|
if (nmax > DNS_NAME_MAXWIRE) {
|
||||||
|
nmax = DNS_NAME_MAXWIRE;
|
||||||
|
}
|
||||||
|
|
||||||
|
cdata = isc_buffer_current(source);
|
||||||
|
cused = 0;
|
||||||
|
|
||||||
|
current = source->current;
|
||||||
|
biggest_pointer = current;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: The following code is not optimized for speed, but
|
||||||
|
* rather for correctness. Speed will be addressed in the future.
|
||||||
|
*/
|
||||||
|
|
||||||
|
while (current < source->active && !done) {
|
||||||
|
c = *cdata++;
|
||||||
|
current++;
|
||||||
|
if (!seen_pointer) {
|
||||||
|
cused++;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (state) {
|
||||||
|
case fw_start:
|
||||||
|
if (c < 64) {
|
||||||
|
offsets[labels] = nused;
|
||||||
|
labels++;
|
||||||
|
if (nused + c + 1 > nmax) {
|
||||||
|
goto full;
|
||||||
|
}
|
||||||
|
nused += c + 1;
|
||||||
|
*ndata++ = c;
|
||||||
|
if (c == 0) {
|
||||||
|
done = true;
|
||||||
|
}
|
||||||
|
n = c;
|
||||||
|
state = fw_ordinary;
|
||||||
|
} else if (c >= 192) {
|
||||||
|
/*
|
||||||
|
* 14-bit compression pointer
|
||||||
|
*/
|
||||||
|
if (!dns_decompress_getpermitted(dctx)) {
|
||||||
|
return (DNS_R_DISALLOWED);
|
||||||
|
}
|
||||||
|
new_current = c & 0x3F;
|
||||||
|
state = fw_newcurrent;
|
||||||
|
} else {
|
||||||
|
return (DNS_R_BADLABELTYPE);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case fw_ordinary:
|
||||||
|
if (downcase) {
|
||||||
|
c = isc_ascii_tolower(c);
|
||||||
|
}
|
||||||
|
*ndata++ = c;
|
||||||
|
n--;
|
||||||
|
if (n == 0) {
|
||||||
|
state = fw_start;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case fw_newcurrent:
|
||||||
|
new_current *= 256;
|
||||||
|
new_current += c;
|
||||||
|
if (new_current >= biggest_pointer) {
|
||||||
|
return (DNS_R_BADPOINTER);
|
||||||
|
}
|
||||||
|
biggest_pointer = new_current;
|
||||||
|
current = new_current;
|
||||||
|
cdata = (unsigned char *)source->base + current;
|
||||||
|
seen_pointer = true;
|
||||||
|
state = fw_start;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FATAL_ERROR("Unknown state %d", state);
|
||||||
|
/* Does not return. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
return (ISC_R_UNEXPECTEDEND);
|
||||||
|
}
|
||||||
|
|
||||||
|
name->ndata = (unsigned char *)target->base + target->used;
|
||||||
|
name->labels = labels;
|
||||||
|
name->length = nused;
|
||||||
|
name->attributes.absolute = true;
|
||||||
|
|
||||||
|
isc_buffer_forward(source, cused);
|
||||||
|
isc_buffer_add(target, name->length);
|
||||||
|
|
||||||
|
return (ISC_R_SUCCESS);
|
||||||
|
|
||||||
|
full:
|
||||||
|
if (nmax == DNS_NAME_MAXWIRE) {
|
||||||
|
/*
|
||||||
|
* The name did not fit even though we had a buffer
|
||||||
|
* big enough to fit a maximum-length name.
|
||||||
|
*/
|
||||||
|
return (DNS_R_NAMETOOLONG);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* The name might fit if only the caller could give us a
|
||||||
|
* big enough buffer.
|
||||||
|
*/
|
||||||
|
return (ISC_R_NOSPACE);
|
||||||
|
}
|
||||||
|
}
|
21
fuzz/old.h
Normal file
21
fuzz/old.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
/*%
|
||||||
|
* For verifying no functional change in the rewrite of dns_name_fromwire()
|
||||||
|
*/
|
||||||
|
isc_result_t
|
||||||
|
old_name_fromwire(dns_name_t *name, isc_buffer_t *source, dns_decompress_t dctx,
|
||||||
|
unsigned int options, isc_buffer_t *target);
|
1
tests/bench/.gitignore
vendored
1
tests/bench/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
/ascii
|
/ascii
|
||||||
/compress
|
/compress
|
||||||
|
/dns_name_fromwire
|
||||||
/siphash
|
/siphash
|
||||||
|
@ -2,7 +2,8 @@ include $(top_srcdir)/Makefile.top
|
|||||||
|
|
||||||
AM_CPPFLAGS += \
|
AM_CPPFLAGS += \
|
||||||
$(LIBISC_CFLAGS) \
|
$(LIBISC_CFLAGS) \
|
||||||
$(LIBDNS_CFLAGS)
|
$(LIBDNS_CFLAGS) \
|
||||||
|
-I$(top_srcdir)/fuzz
|
||||||
|
|
||||||
LDADD += \
|
LDADD += \
|
||||||
$(LIBISC_LIBS) \
|
$(LIBISC_LIBS) \
|
||||||
@ -11,4 +12,10 @@ LDADD += \
|
|||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
ascii \
|
ascii \
|
||||||
compress \
|
compress \
|
||||||
|
dns_name_fromwire \
|
||||||
siphash
|
siphash
|
||||||
|
|
||||||
|
dns_name_fromwire_SOURCES = \
|
||||||
|
$(top_builddir)/fuzz/old.c \
|
||||||
|
$(top_builddir)/fuzz/old.h \
|
||||||
|
dns_name_fromwire.c
|
||||||
|
145
tests/bench/dns_name_fromwire.c
Normal file
145
tests/bench/dns_name_fromwire.c
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
||||||
|
*
|
||||||
|
* See the COPYRIGHT file distributed with this work for additional
|
||||||
|
* information regarding copyright ownership.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include <isc/ascii.h>
|
||||||
|
#include <isc/buffer.h>
|
||||||
|
#include <isc/random.h>
|
||||||
|
#include <isc/time.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
|
#include <dns/compress.h>
|
||||||
|
#include <dns/fixedname.h>
|
||||||
|
#include <dns/name.h>
|
||||||
|
|
||||||
|
#include "old.h"
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
old_bench(const uint8_t *data, size_t size) {
|
||||||
|
isc_result_t result;
|
||||||
|
dns_fixedname_t fixed;
|
||||||
|
dns_name_t *name = dns_fixedname_initname(&fixed);
|
||||||
|
dns_decompress_t dctx = DNS_DECOMPRESS_PERMITTED;
|
||||||
|
isc_buffer_t buf;
|
||||||
|
uint32_t count = 0;
|
||||||
|
|
||||||
|
isc_buffer_constinit(&buf, data, size);
|
||||||
|
isc_buffer_add(&buf, size);
|
||||||
|
isc_buffer_setactive(&buf, size);
|
||||||
|
|
||||||
|
while (isc_buffer_consumedlength(&buf) < size) {
|
||||||
|
result = old_name_fromwire(name, &buf, dctx, 0, NULL);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_buffer_forward(&buf, 1);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
new_bench(const uint8_t *data, size_t size) {
|
||||||
|
isc_result_t result;
|
||||||
|
dns_fixedname_t fixed;
|
||||||
|
dns_name_t *name = dns_fixedname_initname(&fixed);
|
||||||
|
dns_decompress_t dctx = DNS_DECOMPRESS_PERMITTED;
|
||||||
|
isc_buffer_t buf;
|
||||||
|
uint32_t count = 0;
|
||||||
|
|
||||||
|
isc_buffer_constinit(&buf, data, size);
|
||||||
|
isc_buffer_add(&buf, size);
|
||||||
|
isc_buffer_setactive(&buf, size);
|
||||||
|
|
||||||
|
while (isc_buffer_consumedlength(&buf) < size) {
|
||||||
|
result = dns_name_fromwire(name, &buf, dctx, 0, NULL);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_buffer_forward(&buf, 1);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
return (count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
oldnew_bench(const uint8_t *data, size_t size) {
|
||||||
|
isc_time_t t0;
|
||||||
|
isc_time_now_hires(&t0);
|
||||||
|
uint32_t n1 = old_bench(data, size);
|
||||||
|
isc_time_t t1;
|
||||||
|
isc_time_now_hires(&t1);
|
||||||
|
uint32_t n2 = new_bench(data, size);
|
||||||
|
isc_time_t t2;
|
||||||
|
isc_time_now_hires(&t2);
|
||||||
|
|
||||||
|
double t01 = (double)isc_time_microdiff(&t1, &t0);
|
||||||
|
double t12 = (double)isc_time_microdiff(&t2, &t1);
|
||||||
|
printf(" old %u / %f ms; %f / us\n", n1, t01 / 1000.0, n1 / t01);
|
||||||
|
printf(" new %u / %f ms; %f / us\n", n2, t12 / 1000.0, n2 / t12);
|
||||||
|
printf(" old/new %f or %f\n", t01 / t12, t12 / t01);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define NAMES 1000
|
||||||
|
static uint8_t buf[1024 * NAMES];
|
||||||
|
|
||||||
|
int
|
||||||
|
main(void) {
|
||||||
|
unsigned int p;
|
||||||
|
|
||||||
|
printf("random buffer\n");
|
||||||
|
isc_random_buf(buf, sizeof(buf));
|
||||||
|
oldnew_bench(buf, sizeof(buf));
|
||||||
|
|
||||||
|
p = 0;
|
||||||
|
for (unsigned int name = 0; name < NAMES; name++) {
|
||||||
|
unsigned int start = p;
|
||||||
|
unsigned int prev = p;
|
||||||
|
buf[p++] = 0;
|
||||||
|
for (unsigned int label = 0; label < 127; label++) {
|
||||||
|
unsigned int ptr = prev - start;
|
||||||
|
prev = p;
|
||||||
|
buf[p++] = 1;
|
||||||
|
buf[p++] = 'a';
|
||||||
|
buf[p++] = 0xC0 | (ptr >> 8);
|
||||||
|
buf[p++] = 0xFF & ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
printf("127 compression pointers\n");
|
||||||
|
oldnew_bench(buf, p);
|
||||||
|
|
||||||
|
p = 0;
|
||||||
|
for (unsigned int name = 0; name < NAMES; name++) {
|
||||||
|
for (unsigned int label = 0; label < 127; label++) {
|
||||||
|
buf[p++] = 1;
|
||||||
|
buf[p++] = 'a';
|
||||||
|
}
|
||||||
|
buf[p++] = 0;
|
||||||
|
}
|
||||||
|
printf("127 sequential labels\n");
|
||||||
|
oldnew_bench(buf, p);
|
||||||
|
|
||||||
|
p = 0;
|
||||||
|
for (unsigned int name = 0; name < NAMES; name++) {
|
||||||
|
for (unsigned int label = 0; label < 4; label++) {
|
||||||
|
buf[p++] = 62;
|
||||||
|
for (unsigned int c = 0; c < 62; c++) {
|
||||||
|
buf[p++] = 'a';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buf[p++] = 0;
|
||||||
|
}
|
||||||
|
printf("4 long sequential labels\n");
|
||||||
|
oldnew_bench(buf, p);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user