mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-08 19:02:05 -04:00
Convert Stream DNS to use isc_buffer API
Drop the whole isc_dnsbuffer API and use new improved isc_buffer API that provides same functionality as the isc_dnsbuffer unit now.
This commit is contained in:
parent
849d7292ad
commit
6cb6373b5a
6 changed files with 200 additions and 648 deletions
|
|
@ -1521,7 +1521,6 @@ gcov:
|
|||
- for SRC in dns isc; do for DST in dns isc ns; do cp -f "lib/${SRC}/include/${SRC}"/*.h "lib/${DST}/"; done; done
|
||||
- find bin lib -maxdepth 1 -mindepth 1 -type d -exec cp -f lib/isc/include/isc/buffer.h "{}" \;
|
||||
- cp -f lib/isc/include/isc/buffer.h lib/isc/netmgr/buffer.h
|
||||
- cp -f lib/isc/include/isc/dnsbuffer.h lib/isc/netmgr/dnsbuffer.h
|
||||
- cp -f lib/isc/include/isc/dnsstream.h lib/isc/netmgr/dnsstream.h
|
||||
# Help gcovr find dlz_dbi.c file
|
||||
- for DST in ldap mysql mysqldyn sqlite3 wildcard; do cp contrib/dlz/modules/common/dlz_dbi.c "contrib/dlz/modules/${DST}"; done
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ libisc_la_HEADERS = \
|
|||
include/isc/crc64.h \
|
||||
include/isc/deprecated.h \
|
||||
include/isc/dir.h \
|
||||
include/isc/dnsbuffer.h \
|
||||
include/isc/dnsstream.h \
|
||||
include/isc/endian.h \
|
||||
include/isc/entropy.h \
|
||||
|
|
|
|||
|
|
@ -1,446 +0,0 @@
|
|||
/*
|
||||
* 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
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/region.h>
|
||||
#include <isc/util.h>
|
||||
|
||||
#define ISC_DNSBUFFER_STATIC_BUFFER_SIZE (512)
|
||||
#define ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE (ISC_BUFFER_INCR * 2)
|
||||
|
||||
typedef struct isc_dnsbuffer {
|
||||
isc_buffer_t *current; /* pointer to the currently used buffer */
|
||||
isc_buffer_t stbuf; /* static memory buffer */
|
||||
uint8_t buf[ISC_DNSBUFFER_STATIC_BUFFER_SIZE]; /* storage for the static
|
||||
buffer */
|
||||
isc_buffer_t *dynbuf; /* resizeable dynamic memory buffer */
|
||||
isc_mem_t *mctx;
|
||||
} isc_dnsbuffer_t;
|
||||
/*
|
||||
* The 'isc_dnsbuffer_t' object implementation is a thin wrapper on
|
||||
* top of 'isc_buffer_t' which has the following characteristics:
|
||||
*
|
||||
* - provides interface specifically atuned for handling/generating
|
||||
* DNS messages, especially in the format used for DNS messages over
|
||||
* TCP;
|
||||
*
|
||||
* - avoids allocating dynamic memory when handling small DNS
|
||||
* messages, while transparently switching to using dynamic memory
|
||||
* when handling larger messages. This approach significantly
|
||||
* reduces pressure on the memory allocator, as most of the DNS
|
||||
* messages are small.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_init(isc_dnsbuffer_t *restrict dnsbuf, isc_mem_t *memctx);
|
||||
/*!<
|
||||
* \brief Initialise the 'isc_dnsbuffer_t' object, keep a reference to
|
||||
* 'memctx' inside the object.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL;
|
||||
*\li 'memctx' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_uninit(isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Un-initialise the 'isc_dnsbuffer_t' object, de-allocate any
|
||||
*dynamically allocated memory, detach from an internal memory context
|
||||
* reference.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline isc_dnsbuffer_t *
|
||||
isc_dnsbuffer_new(isc_mem_t *memctx);
|
||||
/*!<
|
||||
* \brief Allocate and initialise a new 'isc_dnsbuffer_t' object, keep a
|
||||
* reference to 'memctx' inside the object.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL;
|
||||
*\li 'memctx' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_free(isc_dnsbuffer_t **restrict pdnsbuf);
|
||||
/*!<
|
||||
* \brief Un-initialise and de-allocate the given 'isc_dnsbuffer_t' object.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'pdnsbuf' is not NULL;
|
||||
*\li 'pdnsbuf' does not point to NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_clear(isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Clear the given 'isc_dnsbuffer_t' object (make it empty).
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline unsigned int
|
||||
isc_dnsbuffer_length(const isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Return the total length of the internal memory buffer of
|
||||
* the given 'isc_dnsbuffer_t' object.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline unsigned int
|
||||
isc_dnsbuffer_usedlength(const isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Return the total number of used bytes from the internal
|
||||
* memory buffer of the given 'isc_dnsbuffer_t' object.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline unsigned int
|
||||
isc_dnsbuffer_remaininglength(const isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Return the total number of remaining (unprocessed data)
|
||||
* bytes from the internal memory buffer of the given
|
||||
* 'isc_dnsbuffer_t' object.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_remainingregion(const isc_dnsbuffer_t *restrict dnsbuf,
|
||||
isc_region_t *region);
|
||||
/*!<
|
||||
* \brief Make the given 'isc_region_t' object reference remaining
|
||||
* (unprocessed) data from the internal memory buffer of the given
|
||||
* 'isc_dnsbuffer_t' object.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_compact(const isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Compact the internal used memory region of the internal
|
||||
* memory buffer of the given 'isc_dnsbuffer_t' object so that it
|
||||
* occurs at the start of the memory buffer. Then used region is
|
||||
* shrunk by the size of the processed (consumed) region, and the
|
||||
* consumed region is then made empty. This way the previously
|
||||
* processed (consumed) amount of memory can be used again without
|
||||
* resizing/reallocating the buffer.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline bool
|
||||
isc_dnsbuffer_trycompact(const isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Compact the internal used memory region of the internal
|
||||
* memory buffer of the given 'isc_dnsbuffer_t' object in the case
|
||||
* when the processed (consumed) region is larger or equal in size to
|
||||
* the unprocessed one.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_consume(isc_dnsbuffer_t *restrict dnsbuf, const unsigned int n);
|
||||
/*!<
|
||||
* \brief Consume the given number of bytes from the beginning of
|
||||
* the unprocessed data region of the given 'isc_dnsbuffer_t' object.
|
||||
* The call moves the 'current' unprocessed data region pointer by the
|
||||
* given number of bytes.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_putmem(isc_dnsbuffer_t *restrict dnsbuf, void *buf,
|
||||
const unsigned int buf_size);
|
||||
/*!<
|
||||
* \brief Copy 'buf_size' bytes from the location pointed to by
|
||||
* 'buf' pointer to the end of the unprocessed data region of the
|
||||
* given 'isc_dnsbuffer_t' object. Resize/reallocate the internal
|
||||
* memory buffer if it is too small.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL;
|
||||
*\li 'buf' is not NULL;
|
||||
*\li 'buf_size' is greater than '0'.
|
||||
*/
|
||||
|
||||
static inline uint8_t *
|
||||
isc_dnsbuffer_current(const isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Return the pointer to the beginning of unprocessed data
|
||||
* region of the given 'isc_dnsbuffer_t' object ("current pointer").
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline uint16_t
|
||||
isc_dnsbuffer_peek_uint16be(const isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Lookup an unsigned short (16-bit) value in
|
||||
* big-endian/network byte order at the beginning of unprocessed data
|
||||
* region of the given 'isc_dnsbuffer_t' object.
|
||||
*
|
||||
* If there is not enough data available in the region, '0' will be
|
||||
* returned.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline uint16_t
|
||||
isc_dnsbuffer_consume_uint16be(isc_dnsbuffer_t *restrict dnsbuf);
|
||||
/*!<
|
||||
* \brief Read an unsigned short (16-bit) value in
|
||||
* big-endian/network byte order at the beginning of unprocessed data
|
||||
* region of the given 'isc_dnsbuffer_t' object.
|
||||
*
|
||||
* If there is not enough data available in the region, '0' will be
|
||||
* returned.
|
||||
*
|
||||
* In the case, when the data has been read successfully, the start of
|
||||
* the unprocessed data region is advanced by two bytes.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_putmem_uint16be(isc_dnsbuffer_t *restrict dnsbuf,
|
||||
const uint16_t v);
|
||||
/*!<
|
||||
* \brief Append a given unsigned short (16-bit) value 'v' converted
|
||||
* into big-endian/network byte order at the end of unprocessed data
|
||||
* region of the given 'isc_dnsbuffer_t' object. Resize/reallocate the
|
||||
* internal memory buffer if it is too small to hold the appended data.
|
||||
*
|
||||
* Requires:
|
||||
*\li 'dnsbuf' is not NULL.
|
||||
*/
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_init(isc_dnsbuffer_t *restrict dnsbuf, isc_mem_t *memctx) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
REQUIRE(memctx != NULL);
|
||||
*dnsbuf = (isc_dnsbuffer_t){ .current = &dnsbuf->stbuf };
|
||||
isc_buffer_init(&dnsbuf->stbuf, &dnsbuf->buf[0], sizeof(dnsbuf->buf));
|
||||
isc_mem_attach(memctx, &dnsbuf->mctx);
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_uninit(isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
isc_buffer_clear(&dnsbuf->stbuf);
|
||||
if (dnsbuf->dynbuf != NULL) {
|
||||
isc_buffer_free(&dnsbuf->dynbuf);
|
||||
}
|
||||
|
||||
if (dnsbuf->mctx != NULL) {
|
||||
isc_mem_detach(&dnsbuf->mctx);
|
||||
}
|
||||
}
|
||||
|
||||
static inline isc_dnsbuffer_t *
|
||||
isc_dnsbuffer_new(isc_mem_t *memctx) {
|
||||
isc_dnsbuffer_t *newbuf;
|
||||
|
||||
REQUIRE(memctx != NULL);
|
||||
|
||||
newbuf = isc_mem_get(memctx, sizeof(*newbuf));
|
||||
isc_dnsbuffer_init(newbuf, memctx);
|
||||
|
||||
return (newbuf);
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_free(isc_dnsbuffer_t **restrict pdnsbuf) {
|
||||
isc_dnsbuffer_t *restrict buf = NULL;
|
||||
isc_mem_t *memctx = NULL;
|
||||
REQUIRE(pdnsbuf != NULL && *pdnsbuf != NULL);
|
||||
|
||||
buf = *pdnsbuf;
|
||||
|
||||
isc_mem_attach(buf->mctx, &memctx);
|
||||
isc_dnsbuffer_uninit(buf);
|
||||
isc_mem_putanddetach(&memctx, buf, sizeof(*buf));
|
||||
|
||||
*pdnsbuf = NULL;
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_clear(isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
isc_buffer_clear(dnsbuf->current);
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
isc_dnsbuffer_length(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
return (isc_buffer_length(dnsbuf->current));
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
isc_dnsbuffer_usedlength(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
return (isc_buffer_usedlength(dnsbuf->current));
|
||||
}
|
||||
|
||||
static inline unsigned int
|
||||
isc_dnsbuffer_remaininglength(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
return (isc_buffer_remaininglength(dnsbuf->current));
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_remainingregion(const isc_dnsbuffer_t *restrict dnsbuf,
|
||||
isc_region_t *region) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
REQUIRE(region != NULL);
|
||||
isc_buffer_remainingregion(dnsbuf->current, region);
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_compact(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
isc_buffer_compact(dnsbuf->current);
|
||||
}
|
||||
|
||||
static inline bool
|
||||
isc_dnsbuffer_trycompact(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
if (isc_buffer_consumedlength(dnsbuf->current) >=
|
||||
isc_dnsbuffer_remaininglength(dnsbuf))
|
||||
{
|
||||
isc_dnsbuffer_compact(dnsbuf);
|
||||
return (true);
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_consume(isc_dnsbuffer_t *restrict dnsbuf, const unsigned int n) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
isc_buffer_forward(dnsbuf->current, n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_putmem(isc_dnsbuffer_t *restrict dnsbuf, void *buf,
|
||||
const unsigned int buf_size) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
REQUIRE(buf != NULL);
|
||||
REQUIRE(buf_size > 0);
|
||||
if (!(dnsbuf->current == &dnsbuf->stbuf &&
|
||||
isc_buffer_availablelength(dnsbuf->current) >= buf_size) &&
|
||||
dnsbuf->dynbuf == NULL)
|
||||
{
|
||||
isc_region_t remaining = { 0 };
|
||||
unsigned int total_size = 0;
|
||||
|
||||
isc_buffer_remainingregion(&dnsbuf->stbuf, &remaining);
|
||||
total_size = remaining.length + buf_size;
|
||||
if (total_size < ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE) {
|
||||
total_size = ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE;
|
||||
}
|
||||
isc_buffer_allocate(dnsbuf->mctx, &dnsbuf->dynbuf, total_size);
|
||||
isc_buffer_setautorealloc(dnsbuf->dynbuf, true);
|
||||
if (remaining.length > 0) {
|
||||
isc_buffer_putmem(dnsbuf->dynbuf, remaining.base,
|
||||
remaining.length);
|
||||
}
|
||||
|
||||
dnsbuf->current = dnsbuf->dynbuf;
|
||||
}
|
||||
|
||||
isc_buffer_putmem(dnsbuf->current, buf, buf_size);
|
||||
}
|
||||
|
||||
static inline uint8_t *
|
||||
isc_dnsbuffer_current(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
return (isc_buffer_current(dnsbuf->current));
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
isc__dnsbuffer_peek_uint16be(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
uint16_t v;
|
||||
uint8_t *p = (uint8_t *)isc_dnsbuffer_current(dnsbuf);
|
||||
|
||||
v = p[0] << 8;
|
||||
v |= p[1] & 0xFF;
|
||||
|
||||
return (v);
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
isc_dnsbuffer_peek_uint16be(const isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
if (isc_dnsbuffer_remaininglength(dnsbuf) < sizeof(uint16_t)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
return (isc__dnsbuffer_peek_uint16be(dnsbuf));
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
isc_dnsbuffer_consume_uint16be(isc_dnsbuffer_t *restrict dnsbuf) {
|
||||
uint16_t v;
|
||||
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
|
||||
if (isc_dnsbuffer_remaininglength(dnsbuf) < sizeof(uint16_t)) {
|
||||
return (0);
|
||||
}
|
||||
|
||||
v = isc__dnsbuffer_peek_uint16be(dnsbuf);
|
||||
|
||||
isc_dnsbuffer_consume(dnsbuf, sizeof(uint16_t));
|
||||
|
||||
return (v);
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsbuffer_putmem_uint16be(isc_dnsbuffer_t *restrict dnsbuf,
|
||||
const uint16_t v) {
|
||||
uint8_t b[2] = { 0 };
|
||||
|
||||
REQUIRE(dnsbuf != NULL);
|
||||
|
||||
b[0] = v >> 8;
|
||||
b[1] = v & 0xFF;
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, b, sizeof(b));
|
||||
}
|
||||
|
|
@ -12,12 +12,13 @@
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include <isc/dnsbuffer.h>
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/mem.h>
|
||||
|
||||
typedef struct isc_dnsstream_assembler isc_dnsstream_assembler_t;
|
||||
/*!<
|
||||
* \brief The 'isc_dnsstream_assembler_t' object is built on top of
|
||||
* 'isc_dnsbuffer_t' and intended to encapsulate the state machine
|
||||
* 'isc_buffer_t' and intended to encapsulate the state machine
|
||||
* used for handling DNS messages received in the format used for
|
||||
* messages transmitted over TCP.
|
||||
*
|
||||
|
|
@ -34,7 +35,7 @@ typedef struct isc_dnsstream_assembler isc_dnsstream_assembler_t;
|
|||
* itself makes it trivial to write unit tests for it, leading to
|
||||
* better verification of its correctness. Another important aspect
|
||||
* of its functioning is directly related to the fact that it is built
|
||||
* on top of 'isc_dnsbuffer_t', which tries to manage memory in a
|
||||
* on top of 'isc_buffer_t', which tries to manage memory in a
|
||||
* smart way. In particular:
|
||||
*
|
||||
*\li It tries to use a static buffer for smaller messages, reducing
|
||||
|
|
@ -86,9 +87,12 @@ more;
|
|||
message (i.e. someone attempts to send us junk data).
|
||||
*/
|
||||
|
||||
#define ISC_DNSSTREAM_STATIC_BUFFER_SIZE (512)
|
||||
|
||||
struct isc_dnsstream_assembler {
|
||||
isc_dnsbuffer_t dnsbuf; /*!< Internal buffer for assembling DNS
|
||||
isc_buffer_t dnsbuf; /*!< Internal buffer for assembling DNS
|
||||
messages. */
|
||||
uint8_t buf[ISC_DNSSTREAM_STATIC_BUFFER_SIZE];
|
||||
isc_dnsstream_assembler_cb_t onmsg_cb; /*!< Data processing callback. */
|
||||
void *cbarg; /*!< Callback argument. */
|
||||
bool calling_cb; /*<! Callback calling marker. Used to detect recursive
|
||||
|
|
@ -226,7 +230,9 @@ isc_dnsstream_assembler_init(isc_dnsstream_assembler_t *restrict dnsasm,
|
|||
*dnsasm = (isc_dnsstream_assembler_t){ .result = ISC_R_UNSET };
|
||||
isc_dnsstream_assembler_setcb(dnsasm, cb, cbarg);
|
||||
isc_mem_attach(memctx, &dnsasm->mctx);
|
||||
isc_dnsbuffer_init(&dnsasm->dnsbuf, memctx);
|
||||
|
||||
isc_buffer_init(&dnsasm->dnsbuf, dnsasm->buf, sizeof(dnsasm->buf));
|
||||
isc_buffer_setmctx(&dnsasm->dnsbuf, dnsasm->mctx);
|
||||
}
|
||||
|
||||
static inline void
|
||||
|
|
@ -237,7 +243,8 @@ isc_dnsstream_assembler_uninit(isc_dnsstream_assembler_t *restrict dnsasm) {
|
|||
* make any sense.
|
||||
*/
|
||||
INSIST(dnsasm->calling_cb == false);
|
||||
isc_dnsbuffer_uninit(&dnsasm->dnsbuf);
|
||||
isc_buffer_clearmctx(&dnsasm->dnsbuf);
|
||||
isc_buffer_invalidate(&dnsasm->dnsbuf);
|
||||
if (dnsasm->mctx != NULL) {
|
||||
isc_mem_detach(&dnsasm->mctx);
|
||||
}
|
||||
|
|
@ -286,40 +293,52 @@ isc__dnsstream_assembler_handle_message(
|
|||
isc_dnsstream_assembler_t *restrict dnsasm, void *userarg) {
|
||||
bool cont = false;
|
||||
isc_region_t region = { 0 };
|
||||
uint16_t dnslen = 0;
|
||||
isc_result_t result;
|
||||
uint16_t dnslen = isc_dnsbuffer_peek_uint16be(&dnsasm->dnsbuf);
|
||||
|
||||
INSIST(dnsasm->calling_cb == false);
|
||||
|
||||
if (isc_dnsbuffer_remaininglength(&dnsasm->dnsbuf) < sizeof(uint16_t)) {
|
||||
result = ISC_R_NOMORE;
|
||||
} else if (isc_dnsbuffer_remaininglength(&dnsasm->dnsbuf) >=
|
||||
sizeof(uint16_t) &&
|
||||
dnslen == 0)
|
||||
{
|
||||
/*
|
||||
* Someone seems to send us binary junk or output from /dev/zero
|
||||
*/
|
||||
result = ISC_R_RANGE;
|
||||
isc_dnsbuffer_clear(&dnsasm->dnsbuf);
|
||||
} else if (dnslen <= (isc_dnsbuffer_remaininglength(&dnsasm->dnsbuf) -
|
||||
result = isc_buffer_peekuint16(&dnsasm->dnsbuf, &dnslen);
|
||||
|
||||
switch (result) {
|
||||
case ISC_R_SUCCESS:
|
||||
if (dnslen == 0) {
|
||||
/* This didn't make much sense to me: */
|
||||
/* isc_buffer_remaininglength(&dnsasm->dnsbuf) >=
|
||||
* sizeof(uint16_t) && */
|
||||
|
||||
/*
|
||||
* Someone seems to send us binary junk or output from
|
||||
* /dev/zero
|
||||
*/
|
||||
result = ISC_R_RANGE;
|
||||
isc_buffer_clear(&dnsasm->dnsbuf);
|
||||
break;
|
||||
}
|
||||
|
||||
if (dnslen > (isc_buffer_remaininglength(&dnsasm->dnsbuf) -
|
||||
sizeof(uint16_t)))
|
||||
{
|
||||
result = ISC_R_SUCCESS;
|
||||
} else {
|
||||
result = ISC_R_NOMORE;
|
||||
{
|
||||
result = ISC_R_NOMORE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case ISC_R_NOMORE:
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
dnsasm->result = result;
|
||||
dnsasm->calling_cb = true;
|
||||
if (result == ISC_R_SUCCESS) {
|
||||
(void)isc_dnsbuffer_consume_uint16be(&dnsasm->dnsbuf);
|
||||
isc_dnsbuffer_remainingregion(&dnsasm->dnsbuf, ®ion);
|
||||
(void)isc_buffer_getuint16(&dnsasm->dnsbuf);
|
||||
isc_buffer_remainingregion(&dnsasm->dnsbuf, ®ion);
|
||||
region.length = dnslen;
|
||||
cont = dnsasm->onmsg_cb(dnsasm, ISC_R_SUCCESS, ®ion,
|
||||
dnsasm->cbarg, userarg);
|
||||
if (isc_dnsbuffer_remaininglength(&dnsasm->dnsbuf) >= dnslen) {
|
||||
isc_dnsbuffer_consume(&dnsasm->dnsbuf, dnslen);
|
||||
if (isc_buffer_remaininglength(&dnsasm->dnsbuf) >= dnslen) {
|
||||
isc_buffer_forward(&dnsasm->dnsbuf, dnslen);
|
||||
}
|
||||
} else {
|
||||
cont = false;
|
||||
|
|
@ -342,15 +361,15 @@ isc_dnsstream_assembler_incoming(isc_dnsstream_assembler_t *restrict dnsasm,
|
|||
INSIST(buf == NULL);
|
||||
} else {
|
||||
INSIST(buf != NULL);
|
||||
isc_dnsbuffer_putmem(&dnsasm->dnsbuf, buf, buf_size);
|
||||
isc_buffer_putmem(&dnsasm->dnsbuf, buf, buf_size);
|
||||
}
|
||||
|
||||
while (isc__dnsstream_assembler_handle_message(dnsasm, userarg)) {
|
||||
if (isc_dnsbuffer_remaininglength(&dnsasm->dnsbuf) == 0) {
|
||||
if (isc_buffer_remaininglength(&dnsasm->dnsbuf) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
isc_dnsbuffer_trycompact(&dnsasm->dnsbuf);
|
||||
isc_buffer_trycompact(&dnsasm->dnsbuf);
|
||||
}
|
||||
|
||||
static inline isc_result_t
|
||||
|
|
@ -366,13 +385,13 @@ isc_dnsstream_assembler_remaininglength(
|
|||
const isc_dnsstream_assembler_t *restrict dnsasm) {
|
||||
REQUIRE(dnsasm != NULL);
|
||||
|
||||
return (isc_dnsbuffer_remaininglength(&dnsasm->dnsbuf));
|
||||
return (isc_buffer_remaininglength(&dnsasm->dnsbuf));
|
||||
}
|
||||
|
||||
static inline void
|
||||
isc_dnsstream_assembler_clear(isc_dnsstream_assembler_t *restrict dnsasm) {
|
||||
REQUIRE(dnsasm != NULL);
|
||||
|
||||
isc_dnsbuffer_clear(&dnsasm->dnsbuf);
|
||||
isc_buffer_clear(&dnsasm->dnsbuf);
|
||||
dnsasm->result = ISC_R_UNSET;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include <isc/atomic.h>
|
||||
#include <isc/dnsbuffer.h>
|
||||
#include <isc/result.h>
|
||||
#include <isc/thread.h>
|
||||
|
||||
|
|
@ -24,15 +23,14 @@
|
|||
/*
|
||||
* Stream DNS is a unified transport capable of serving both DNS over
|
||||
* TCP and DNS over TLS. It is built on top of
|
||||
* 'isc_dnsstream_assembler_t' and 'isc_dnsbuffer_t'. The first one
|
||||
* is used for assembling DNS messages in the format used for DNS over
|
||||
* TCP out of incoming data and is built on top of
|
||||
* 'isc_dnsbuffer_t'. The 'isc_dnbuffer_t' is a thin wrapper on top of
|
||||
* 'isc_buffer_t' and is optimised for small (>= 512 bytes) DNS
|
||||
* messages. For small messages it uses a small static memory buffer,
|
||||
* but it can automatically switch to a dynamically allocated memory
|
||||
* buffer for larger ones. This way we avoid unnecessary memory
|
||||
* allocation requests in most cases, as most DNS messages are small.
|
||||
* 'isc_dnsstream_assembler_t' which is used for assembling DNS
|
||||
* messages in the format used for DNS over TCP out of incoming data.
|
||||
* It is built on top of 'isc_buffer_t' optimised for small (>= 512
|
||||
* bytes) DNS messages. For small messages it uses a small static
|
||||
* memory buffer, but it can automatically switch to a larger
|
||||
* dynamically allocated memory buffer for larger ones. This way we
|
||||
* avoid unnecessary memory allocation requests in most cases, as most
|
||||
* DNS messages are small.
|
||||
*
|
||||
* The use of 'isc_dnsstream_assembler_t' allows decoupling DNS
|
||||
* message assembling code from networking code itself, making it
|
||||
|
|
@ -47,22 +45,12 @@
|
|||
* The writing is done in a simpler manner due to the fact that we
|
||||
* have full control over the data. For each write request we attempt
|
||||
* to allocate a 'streamdns_send_req_t' structure, whose main purpose
|
||||
* is to keep the data required for the send request processing. An
|
||||
* 'isc_dnsbuffer_t' object is used as a data storage for the reasons
|
||||
* described above.
|
||||
* is to keep the data required for the send request processing.
|
||||
*
|
||||
* When processing write requests there is an important optimisation:
|
||||
* we attempt to reuse 'streamdns_send_req_t' objects again, in order
|
||||
* to avoid memory allocations when:
|
||||
*
|
||||
* a) requesting memory for the new 'streamdns_send_req_t' object;
|
||||
*
|
||||
* b) resizing the 'isc_dnsbuffer_t' to fit large messages, should it
|
||||
* be required.
|
||||
*
|
||||
* The last characteristic is important as it allows gradually growing
|
||||
* the reused send buffer in a lazy manner when transmitting multiple
|
||||
* DNS messages (e.g. during zone transfers).
|
||||
* to avoid memory allocations when requesting memory for the new
|
||||
* 'streamdns_send_req_t' object.
|
||||
*
|
||||
* To understand how sending is done, start by looking at
|
||||
* 'isc__nm_async_streamdnssend()'. Additionally also take a look at
|
||||
|
|
@ -1147,7 +1135,7 @@ isc__nm_streamdns_verify_tls_peer_result_string(const isc_nmhandle_t *handle) {
|
|||
return (sock->streamdns.tls_verify_error);
|
||||
}
|
||||
|
||||
return (false);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#define UNIT_TESTING
|
||||
#include <cmocka.h>
|
||||
|
||||
#include <isc/buffer.h>
|
||||
#include <isc/dnsstream.h>
|
||||
#include <isc/mem.h>
|
||||
#include <isc/os.h>
|
||||
|
|
@ -34,17 +35,20 @@
|
|||
|
||||
#include <tests/isc.h>
|
||||
|
||||
#define STATIC_BUFFER_SIZE (512)
|
||||
#define DYNAMIC_BUFFER_SIZE (STATIC_BUFFER_SIZE + ISC_BUFFER_INCR)
|
||||
|
||||
static int
|
||||
setup_test_dnsbuf(void **state) {
|
||||
isc_dnsbuffer_t **pdnsbuf = (isc_dnsbuffer_t **)state;
|
||||
*pdnsbuf = isc_dnsbuffer_new(mctx);
|
||||
isc_buffer_t **pdnsbuf = (isc_buffer_t **)state;
|
||||
isc_buffer_allocate(mctx, pdnsbuf, STATIC_BUFFER_SIZE);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
teardown_test_dnsbuf(void **state) {
|
||||
isc_dnsbuffer_free((isc_dnsbuffer_t **)state);
|
||||
isc_buffer_free((isc_buffer_t **)state);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -77,8 +81,8 @@ teardown_test_dnsasm(void **state) {
|
|||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(dnsbuffer_generic_test) {
|
||||
uint8_t buf[ISC_DNSBUFFER_STATIC_BUFFER_SIZE / 2] = { 0 };
|
||||
isc_dnsbuffer_t *dnsbuf = (isc_dnsbuffer_t *)*state;
|
||||
uint8_t buf[STATIC_BUFFER_SIZE / 2] = { 0 };
|
||||
isc_buffer_t *dnsbuf = (isc_buffer_t *)*state;
|
||||
isc_region_t reg = { 0 };
|
||||
size_t n = 0;
|
||||
|
||||
|
|
@ -87,88 +91,74 @@ ISC_RUN_TEST_IMPL(dnsbuffer_generic_test) {
|
|||
}
|
||||
|
||||
/* sanity checks */
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) ==
|
||||
ISC_DNSBUFFER_STATIC_BUFFER_SIZE);
|
||||
assert_true(isc_dnsbuffer_usedlength(dnsbuf) == 0);
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_length(dnsbuf) == STATIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_usedlength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
|
||||
assert_true(isc_dnsbuffer_usedlength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_buffer_usedlength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
|
||||
assert_true(isc_dnsbuffer_current(dnsbuf) == dnsbuf->buf);
|
||||
assert_true(dnsbuf->current == &dnsbuf->stbuf);
|
||||
assert_true(isc_buffer_current(dnsbuf) == dnsbuf->base);
|
||||
|
||||
isc_dnsbuffer_clear(dnsbuf);
|
||||
isc_buffer_clear(dnsbuf);
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) ==
|
||||
ISC_DNSBUFFER_STATIC_BUFFER_SIZE);
|
||||
assert_true(isc_dnsbuffer_usedlength(dnsbuf) == 0);
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_length(dnsbuf) == STATIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_usedlength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
|
||||
assert_true(dnsbuf->current == &dnsbuf->stbuf);
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
assert_true(isc_buffer_usedlength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
|
||||
assert_true(isc_dnsbuffer_usedlength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_buffer_current(dnsbuf) == dnsbuf->base);
|
||||
|
||||
assert_true(isc_dnsbuffer_current(dnsbuf) == dnsbuf->buf);
|
||||
assert_true(dnsbuf->current == &dnsbuf->stbuf);
|
||||
|
||||
for (size_t i = 0; i < sizeof(buf);
|
||||
i++, isc_dnsbuffer_consume(dnsbuf, 1))
|
||||
for (size_t i = 0; i < sizeof(buf); i++, isc_buffer_forward(dnsbuf, 1))
|
||||
{
|
||||
uint8_t *p = isc_dnsbuffer_current(dnsbuf);
|
||||
uint8_t *p = isc_buffer_current(dnsbuf);
|
||||
|
||||
assert_true(*p == i);
|
||||
}
|
||||
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_dnsbuffer_usedlength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_usedlength(dnsbuf) == sizeof(buf));
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_dnsbuffer_usedlength(dnsbuf) == sizeof(buf) * 2);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
assert_true(isc_buffer_usedlength(dnsbuf) == sizeof(buf) * 2);
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) ==
|
||||
ISC_DNSBUFFER_STATIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_length(dnsbuf) == STATIC_BUFFER_SIZE);
|
||||
|
||||
assert_true(dnsbuf->current == &dnsbuf->stbuf);
|
||||
|
||||
for (size_t i = 0; i < sizeof(buf);
|
||||
i++, isc_dnsbuffer_consume(dnsbuf, 1))
|
||||
for (size_t i = 0; i < sizeof(buf); i++, isc_buffer_forward(dnsbuf, 1))
|
||||
{
|
||||
uint8_t *p = isc_dnsbuffer_current(dnsbuf);
|
||||
uint8_t *p = isc_buffer_current(dnsbuf);
|
||||
|
||||
assert_true(*p == i);
|
||||
}
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) ==
|
||||
ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_length(dnsbuf) == DYNAMIC_BUFFER_SIZE);
|
||||
|
||||
for (size_t i = 0; i < sizeof(buf);
|
||||
i++, isc_dnsbuffer_consume(dnsbuf, 1))
|
||||
for (size_t i = 0; i < sizeof(buf); i++, isc_buffer_forward(dnsbuf, 1))
|
||||
{
|
||||
uint8_t *p = isc_dnsbuffer_current(dnsbuf);
|
||||
uint8_t *p = isc_buffer_current(dnsbuf);
|
||||
|
||||
assert_true(*p == i);
|
||||
}
|
||||
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_dnsbuffer_trycompact(dnsbuf));
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
isc_buffer_trycompact(dnsbuf);
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) ==
|
||||
ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_length(dnsbuf) == DYNAMIC_BUFFER_SIZE);
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
|
||||
isc_dnsbuffer_remainingregion(dnsbuf, ®);
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == reg.length);
|
||||
isc_buffer_remainingregion(dnsbuf, ®);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == reg.length);
|
||||
assert_true(reg.length == sizeof(buf));
|
||||
|
||||
for (size_t i = 0; i < reg.length; i++) {
|
||||
|
|
@ -177,35 +167,33 @@ ISC_RUN_TEST_IMPL(dnsbuffer_generic_test) {
|
|||
assert_true(d == i);
|
||||
}
|
||||
|
||||
isc_dnsbuffer_consume(dnsbuf, reg.length);
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
isc_buffer_forward(dnsbuf, reg.length);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == sizeof(buf));
|
||||
|
||||
isc_dnsbuffer_clear(dnsbuf);
|
||||
isc_buffer_clear(dnsbuf);
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) ==
|
||||
ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_length(dnsbuf) == DYNAMIC_BUFFER_SIZE);
|
||||
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
|
||||
n = ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE / sizeof(buf) + 1;
|
||||
n = DYNAMIC_BUFFER_SIZE / sizeof(buf) + 1;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) >
|
||||
ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE);
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) >= n * sizeof(buf));
|
||||
assert_true(isc_buffer_length(dnsbuf) > DYNAMIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_length(dnsbuf) >= n * sizeof(buf));
|
||||
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == n * sizeof(buf));
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == n * sizeof(buf));
|
||||
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
for (size_t k = 0; k < sizeof(buf);
|
||||
k++, isc_dnsbuffer_consume(dnsbuf, 1))
|
||||
k++, isc_buffer_forward(dnsbuf, 1))
|
||||
{
|
||||
uint8_t *p = isc_dnsbuffer_current(dnsbuf);
|
||||
uint8_t *p = isc_buffer_current(dnsbuf);
|
||||
|
||||
assert_true(*p == k);
|
||||
}
|
||||
|
|
@ -213,64 +201,61 @@ ISC_RUN_TEST_IMPL(dnsbuffer_generic_test) {
|
|||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(dnsbuffer_resize_alloc_test) {
|
||||
uint8_t buf[ISC_DNSBUFFER_STATIC_BUFFER_SIZE / 2] = { 0 };
|
||||
isc_dnsbuffer_t *dnsbuf = (isc_dnsbuffer_t *)*state;
|
||||
uint8_t buf[STATIC_BUFFER_SIZE / 2] = { 0 };
|
||||
isc_buffer_t *dnsbuf = (isc_buffer_t *)*state;
|
||||
size_t i = 0, n = 0;
|
||||
|
||||
for (i = 0; i < sizeof(buf); i++) {
|
||||
buf[i] = (uint8_t)i;
|
||||
}
|
||||
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
|
||||
for (i = 0; i < (sizeof(buf) / 3) * 2;
|
||||
i++, isc_dnsbuffer_consume(dnsbuf, 1))
|
||||
i++, isc_buffer_forward(dnsbuf, 1))
|
||||
{
|
||||
uint8_t *p = isc_dnsbuffer_current(dnsbuf);
|
||||
uint8_t *p = isc_buffer_current(dnsbuf);
|
||||
|
||||
assert_true(*p == i);
|
||||
}
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) ==
|
||||
ISC_DNSBUFFER_STATIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_length(dnsbuf) == STATIC_BUFFER_SIZE);
|
||||
|
||||
n = ISC_DNSBUFFER_INITIAL_DYNAMIC_BUFFER_SIZE / sizeof(buf) + 1;
|
||||
n = DYNAMIC_BUFFER_SIZE / sizeof(buf) + 1;
|
||||
for (size_t k = 0; k < n; k++) {
|
||||
isc_dnsbuffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
isc_buffer_putmem(dnsbuf, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
assert_true(isc_dnsbuffer_length(dnsbuf) >=
|
||||
ISC_DNSBUFFER_STATIC_BUFFER_SIZE);
|
||||
assert_true(isc_buffer_length(dnsbuf) >= STATIC_BUFFER_SIZE);
|
||||
|
||||
for (; i < sizeof(buf); i++, isc_dnsbuffer_consume(dnsbuf, 1)) {
|
||||
uint8_t *p = isc_dnsbuffer_current(dnsbuf);
|
||||
for (; i < sizeof(buf); i++, isc_buffer_forward(dnsbuf, 1)) {
|
||||
uint8_t *p = isc_buffer_current(dnsbuf);
|
||||
|
||||
assert_true(*p == i);
|
||||
}
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(dnsbuffer_be_test) {
|
||||
isc_dnsbuffer_t *dnsbuf = (isc_dnsbuffer_t *)*state;
|
||||
isc_buffer_t *dnsbuf = (isc_buffer_t *)*state;
|
||||
const uint16_t u16 = 0xBEEF;
|
||||
uint16_t *pu16;
|
||||
uint16_t u16v;
|
||||
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
|
||||
assert_true(isc_dnsbuffer_peek_uint16be(dnsbuf) == 0);
|
||||
assert_true(isc_dnsbuffer_consume_uint16be(dnsbuf) == 0);
|
||||
isc_buffer_putuint16(dnsbuf, u16);
|
||||
|
||||
isc_dnsbuffer_putmem_uint16be(dnsbuf, u16);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == sizeof(u16));
|
||||
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == sizeof(u16));
|
||||
|
||||
pu16 = (uint16_t *)isc_dnsbuffer_current(dnsbuf);
|
||||
pu16 = (uint16_t *)isc_buffer_current(dnsbuf);
|
||||
assert_true(*pu16 == htons(u16));
|
||||
|
||||
assert_true(isc_dnsbuffer_peek_uint16be(dnsbuf) == u16);
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == sizeof(u16));
|
||||
assert_int_equal(isc_buffer_peekuint16(dnsbuf, &u16v), ISC_R_SUCCESS);
|
||||
assert_int_equal(u16v, u16);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == sizeof(u16));
|
||||
|
||||
assert_true(isc_dnsbuffer_consume_uint16be(dnsbuf) == u16);
|
||||
assert_true(isc_dnsbuffer_remaininglength(dnsbuf) == 0);
|
||||
assert_true(isc_buffer_getuint16(dnsbuf) == u16);
|
||||
assert_true(isc_buffer_remaininglength(dnsbuf) == 0);
|
||||
}
|
||||
|
||||
typedef struct verify_cbdata {
|
||||
|
|
@ -392,17 +377,18 @@ ISC_RUN_TEST_IMPL(dnsasm_sequence_test) {
|
|||
|
||||
ISC_RUN_TEST_IMPL(dnsasm_multiple_messages_test) {
|
||||
isc_dnsstream_assembler_t *dnsasm = (isc_dnsstream_assembler_t *)*state;
|
||||
isc_dnsbuffer_t dnsbuf;
|
||||
isc_buffer_t dnsbuf;
|
||||
verify_cbdata_t cbdata = { 0 };
|
||||
size_t verified = 0;
|
||||
|
||||
isc_dnsbuffer_init(&dnsbuf, mctx);
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)response, sizeof(response));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)request_large,
|
||||
sizeof(request_large));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)response_large,
|
||||
sizeof(response_large));
|
||||
isc_buffer_init(&dnsbuf, NULL, 0);
|
||||
isc_buffer_setmctx(&dnsbuf, mctx);
|
||||
isc_buffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)response, sizeof(response));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)request_large,
|
||||
sizeof(request_large));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)response_large,
|
||||
sizeof(response_large));
|
||||
|
||||
cbdata.cont_on_success = false;
|
||||
|
||||
|
|
@ -411,11 +397,12 @@ ISC_RUN_TEST_IMPL(dnsasm_multiple_messages_test) {
|
|||
*/
|
||||
cbdata.verify_message = (uint8_t *)request;
|
||||
isc_dnsstream_assembler_setcb(dnsasm, verify_dnsmsg, (void *)&cbdata);
|
||||
isc_dnsstream_assembler_incoming(
|
||||
dnsasm, &verified, isc_dnsbuffer_current(&dnsbuf),
|
||||
isc_dnsbuffer_remaininglength(&dnsbuf));
|
||||
isc_dnsstream_assembler_incoming(dnsasm, &verified,
|
||||
isc_buffer_current(&dnsbuf),
|
||||
isc_buffer_remaininglength(&dnsbuf));
|
||||
|
||||
isc_dnsbuffer_uninit(&dnsbuf);
|
||||
isc_buffer_clearmctx(&dnsbuf);
|
||||
isc_buffer_invalidate(&dnsbuf);
|
||||
assert_true(verified == 1);
|
||||
assert_true(isc_dnsstream_assembler_result(dnsasm) == ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -473,26 +460,28 @@ ISC_RUN_TEST_IMPL(dnsasm_error_data_test) {
|
|||
isc_dnsstream_assembler_t *dnsasm = (isc_dnsstream_assembler_t *)*state;
|
||||
verify_cbdata_t cbdata = { 0 };
|
||||
size_t verified = 0;
|
||||
isc_dnsbuffer_t dnsbuf;
|
||||
isc_buffer_t dnsbuf;
|
||||
uint16_t bad_data = 0;
|
||||
|
||||
isc_dnsbuffer_init(&dnsbuf, mctx);
|
||||
isc_buffer_init(&dnsbuf, NULL, 0);
|
||||
isc_buffer_setmctx(&dnsbuf, mctx);
|
||||
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)&bad_data, sizeof(bad_data));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)&bad_data, sizeof(bad_data));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)response_large,
|
||||
sizeof(response_large));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)&bad_data, sizeof(bad_data));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)&bad_data, sizeof(bad_data));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)response_large,
|
||||
sizeof(response_large));
|
||||
|
||||
cbdata.cont_on_success = false;
|
||||
|
||||
cbdata.verify_message = (uint8_t *)request;
|
||||
isc_dnsstream_assembler_setcb(dnsasm, verify_dnsmsg, (void *)&cbdata);
|
||||
isc_dnsstream_assembler_incoming(
|
||||
dnsasm, &verified, isc_dnsbuffer_current(&dnsbuf),
|
||||
isc_dnsbuffer_remaininglength(&dnsbuf));
|
||||
isc_dnsstream_assembler_incoming(dnsasm, &verified,
|
||||
isc_buffer_current(&dnsbuf),
|
||||
isc_buffer_remaininglength(&dnsbuf));
|
||||
|
||||
isc_dnsbuffer_uninit(&dnsbuf);
|
||||
isc_buffer_clearmctx(&dnsbuf);
|
||||
isc_buffer_invalidate(&dnsbuf);
|
||||
|
||||
assert_true(verified == 1);
|
||||
assert_true(isc_dnsstream_assembler_result(dnsasm) == ISC_R_SUCCESS);
|
||||
|
|
@ -513,7 +502,7 @@ ISC_RUN_TEST_IMPL(dnsasm_torn_randomly_test) {
|
|||
isc_dnsstream_assembler_t *dnsasm = (isc_dnsstream_assembler_t *)*state;
|
||||
verify_cbdata_t cbdata = { 0 };
|
||||
verify_regions_cbdata_t cbdata_regions = { 0 };
|
||||
isc_dnsbuffer_t dnsbuf;
|
||||
isc_buffer_t dnsbuf;
|
||||
size_t packetno;
|
||||
isc_region_t packets[] = {
|
||||
{ (void *)request, sizeof(request) },
|
||||
|
|
@ -528,10 +517,11 @@ ISC_RUN_TEST_IMPL(dnsasm_torn_randomly_test) {
|
|||
};
|
||||
const size_t npackets = sizeof(packets) / sizeof(packets[0]);
|
||||
|
||||
isc_dnsbuffer_init(&dnsbuf, mctx);
|
||||
isc_buffer_init(&dnsbuf, NULL, 0);
|
||||
isc_buffer_setmctx(&dnsbuf, mctx);
|
||||
|
||||
for (size_t i = 0; i < npackets; i++) {
|
||||
isc_dnsbuffer_putmem(&dnsbuf, packets[i].base,
|
||||
packets[i].length);
|
||||
isc_buffer_putmem(&dnsbuf, packets[i].base, packets[i].length);
|
||||
}
|
||||
|
||||
/* process packet by packet */
|
||||
|
|
@ -540,9 +530,9 @@ ISC_RUN_TEST_IMPL(dnsasm_torn_randomly_test) {
|
|||
isc_dnsstream_assembler_setcb(dnsasm, verify_dnsmsg, (void *)&cbdata);
|
||||
|
||||
/* process random amount of data */
|
||||
for (; isc_dnsbuffer_remaininglength(&dnsbuf) > 0;) {
|
||||
for (; isc_buffer_remaininglength(&dnsbuf) > 0;) {
|
||||
size_t sz = 1 + isc_random_uniform(
|
||||
isc_dnsbuffer_remaininglength(&dnsbuf));
|
||||
isc_buffer_remaininglength(&dnsbuf));
|
||||
|
||||
for (bool start = true; packetno < npackets; start = false) {
|
||||
cbdata.verify_message =
|
||||
|
|
@ -551,7 +541,7 @@ ISC_RUN_TEST_IMPL(dnsasm_torn_randomly_test) {
|
|||
if (start) {
|
||||
isc_dnsstream_assembler_incoming(
|
||||
dnsasm, &packetno,
|
||||
isc_dnsbuffer_current(&dnsbuf), sz);
|
||||
isc_buffer_current(&dnsbuf), sz);
|
||||
} else {
|
||||
isc_dnsstream_assembler_incoming(
|
||||
dnsasm, &packetno, NULL, 0);
|
||||
|
|
@ -564,16 +554,15 @@ ISC_RUN_TEST_IMPL(dnsasm_torn_randomly_test) {
|
|||
}
|
||||
}
|
||||
|
||||
isc_dnsbuffer_consume(&dnsbuf, sz);
|
||||
isc_buffer_forward(&dnsbuf, sz);
|
||||
}
|
||||
|
||||
assert_true(packetno == npackets);
|
||||
assert_true(isc_dnsstream_assembler_remaininglength(dnsasm) == 0);
|
||||
assert_true(isc_dnsbuffer_remaininglength(&dnsbuf) == 0);
|
||||
assert_true(isc_buffer_remaininglength(&dnsbuf) == 0);
|
||||
|
||||
for (size_t i = 0; i < npackets; i++) {
|
||||
isc_dnsbuffer_putmem(&dnsbuf, packets[i].base,
|
||||
packets[i].length);
|
||||
isc_buffer_putmem(&dnsbuf, packets[i].base, packets[i].length);
|
||||
}
|
||||
|
||||
/* try to process multiple packets at once, when possible */
|
||||
|
|
@ -585,44 +574,48 @@ ISC_RUN_TEST_IMPL(dnsasm_torn_randomly_test) {
|
|||
(void *)&cbdata_regions);
|
||||
|
||||
/* process random amount of data */
|
||||
for (; isc_dnsbuffer_remaininglength(&dnsbuf) > 0;) {
|
||||
for (; isc_buffer_remaininglength(&dnsbuf) > 0;) {
|
||||
size_t sz = 1 + isc_random_uniform(
|
||||
isc_dnsbuffer_remaininglength(&dnsbuf));
|
||||
isc_buffer_remaininglength(&dnsbuf));
|
||||
|
||||
isc_dnsstream_assembler_incoming(
|
||||
dnsasm, &packetno, isc_dnsbuffer_current(&dnsbuf), sz);
|
||||
dnsasm, &packetno, isc_buffer_current(&dnsbuf), sz);
|
||||
|
||||
isc_dnsbuffer_consume(&dnsbuf, sz);
|
||||
isc_buffer_forward(&dnsbuf, sz);
|
||||
}
|
||||
|
||||
assert_true(packetno == npackets);
|
||||
assert_true(isc_dnsstream_assembler_remaininglength(dnsasm) == 0);
|
||||
assert_true(isc_dnsbuffer_remaininglength(&dnsbuf) == 0);
|
||||
assert_true(isc_buffer_remaininglength(&dnsbuf) == 0);
|
||||
|
||||
isc_dnsbuffer_uninit(&dnsbuf);
|
||||
isc_buffer_clearmctx(&dnsbuf);
|
||||
isc_buffer_invalidate(&dnsbuf);
|
||||
dnsasm->cbarg = NULL; /* to make GCC happy about dangling pointers */
|
||||
}
|
||||
|
||||
ISC_RUN_TEST_IMPL(dnsasm_clear_buffer_within_cb_test) {
|
||||
isc_dnsstream_assembler_t *dnsasm = (isc_dnsstream_assembler_t *)*state;
|
||||
verify_cbdata_t cbdata = { 0 };
|
||||
size_t verified = 0;
|
||||
isc_dnsbuffer_t dnsbuf;
|
||||
isc_buffer_t dnsbuf;
|
||||
|
||||
isc_dnsbuffer_init(&dnsbuf, mctx);
|
||||
isc_buffer_init(&dnsbuf, NULL, 0);
|
||||
isc_buffer_setmctx(&dnsbuf, mctx);
|
||||
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)&response, sizeof(response));
|
||||
isc_dnsbuffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)&response, sizeof(response));
|
||||
isc_buffer_putmem(&dnsbuf, (void *)request, sizeof(request));
|
||||
cbdata.cont_on_success = true;
|
||||
cbdata.clear_on_success = true;
|
||||
|
||||
cbdata.verify_message = (uint8_t *)request;
|
||||
isc_dnsstream_assembler_setcb(dnsasm, verify_dnsmsg, (void *)&cbdata);
|
||||
isc_dnsstream_assembler_incoming(
|
||||
dnsasm, &verified, isc_dnsbuffer_current(&dnsbuf),
|
||||
isc_dnsbuffer_remaininglength(&dnsbuf));
|
||||
isc_dnsstream_assembler_incoming(dnsasm, &verified,
|
||||
isc_buffer_current(&dnsbuf),
|
||||
isc_buffer_remaininglength(&dnsbuf));
|
||||
|
||||
isc_dnsbuffer_uninit(&dnsbuf);
|
||||
isc_buffer_clearmctx(&dnsbuf);
|
||||
isc_buffer_invalidate(&dnsbuf);
|
||||
|
||||
assert_true(verified == 1);
|
||||
assert_true(isc_dnsstream_assembler_result(dnsasm) == ISC_R_UNSET);
|
||||
|
|
|
|||
Loading…
Reference in a new issue