diff --git a/bin/named/server.c b/bin/named/server.c index d6f5ed771b..3027bafe75 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -7971,8 +7971,8 @@ data_to_cfg(dns_view_t *view, MDB_val *key, MDB_val *data, isc_buffer_t **text, INSIST(zone_config != NULL && zone_config_len > 0); /* zone zonename { config; }; */ - result = isc_buffer_reserve(text, 6 + zone_name_len + 2 + - zone_config_len + 2); + result = isc_buffer_reserve(*text, 6 + zone_name_len + 2 + + zone_config_len + 2); if (result != ISC_R_SUCCESS) { goto cleanup; } @@ -12474,7 +12474,7 @@ named_server_testgen(isc_lex_t *lex, isc_buffer_t **text) { count = strtoul(ptr, NULL, 10); } - CHECK(isc_buffer_reserve(text, count)); + CHECK(isc_buffer_reserve(*text, count)); for (i = 0; i < count; i++) { CHECK(putuint8(text, chars[i % (sizeof(chars) - 1)])); } @@ -15422,7 +15422,7 @@ static isc_result_t putmem(isc_buffer_t **b, const char *str, size_t len) { isc_result_t result; - result = isc_buffer_reserve(b, (unsigned int)len); + result = isc_buffer_reserve(*b, (unsigned int)len); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } @@ -15440,7 +15440,7 @@ static isc_result_t putuint8(isc_buffer_t **b, uint8_t val) { isc_result_t result; - result = isc_buffer_reserve(b, 1); + result = isc_buffer_reserve(*b, 1); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } diff --git a/bin/tests/wire_test.c b/bin/tests/wire_test.c index 8729fad89f..da25fe17ce 100644 --- a/bin/tests/wire_test.c +++ b/bin/tests/wire_test.c @@ -186,7 +186,7 @@ main(int argc, char *argv[]) { if (rawdata) { while (fread(&c, 1, 1, f) != 0) { - result = isc_buffer_reserve(&input, 1); + result = isc_buffer_reserve(input, 1); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(input, (uint8_t)c); } @@ -223,7 +223,7 @@ main(int argc, char *argv[]) { c = fromhex(*rp++); c *= 16; c += fromhex(*rp++); - result = isc_buffer_reserve(&input, 1); + result = isc_buffer_reserve(input, 1); RUNTIME_CHECK(result == ISC_R_SUCCESS); isc_buffer_putuint8(input, (uint8_t)c); } diff --git a/bin/tools/dnstap-read.c b/bin/tools/dnstap-read.c index 933e76ad04..ee4aae12f5 100644 --- a/bin/tools/dnstap-read.c +++ b/bin/tools/dnstap-read.c @@ -157,7 +157,7 @@ print_packet(dns_dtdata_t *dt, const dns_master_style_t *style) { } for (;;) { - isc_buffer_reserve(&b, textlen); + isc_buffer_reserve(b, textlen); if (b == NULL) { fatal("out of memory"); } diff --git a/lib/dns/adb.c b/lib/dns/adb.c index d105107f95..d096c6185d 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -2713,7 +2713,7 @@ static isc_result_t putstr(isc_buffer_t **b, const char *str) { isc_result_t result; - result = isc_buffer_reserve(b, strlen(str)); + result = isc_buffer_reserve(*b, strlen(str)); if (result != ISC_R_SUCCESS) { return (result); } diff --git a/lib/dns/catz.c b/lib/dns/catz.c index b755e6cce5..56d4ed65bb 100644 --- a/lib/dns/catz.c +++ b/lib/dns/catz.c @@ -1548,7 +1548,6 @@ catz_process_apl(dns_catz_zone_t *zone, isc_buffer_t **aclbp, return (result); } isc_buffer_allocate(zone->catzs->mctx, &aclb, 16); - isc_buffer_setautorealloc(aclb, true); for (result = dns_rdata_apl_first(&rdata_apl); result == ISC_R_SUCCESS; result = dns_rdata_apl_next(&rdata_apl)) { @@ -1568,14 +1567,14 @@ catz_process_apl(dns_catz_zone_t *zone, isc_buffer_t **aclbp, if (apl_ent.negative) { isc_buffer_putuint8(aclb, '!'); } - isc_buffer_reserve(&aclb, INET6_ADDRSTRLEN); + isc_buffer_reserve(aclb, INET6_ADDRSTRLEN); result = isc_netaddr_totext(&addr, aclb); RUNTIME_CHECK(result == ISC_R_SUCCESS); if ((apl_ent.family == 1 && apl_ent.prefix < 32) || (apl_ent.family == 2 && apl_ent.prefix < 128)) { isc_buffer_putuint8(aclb, '/'); - isc_buffer_putdecint(aclb, apl_ent.prefix); + isc_buffer_printf(aclb, "%" PRId8, apl_ent.prefix); } isc_buffer_putstr(aclb, "; "); } @@ -1872,7 +1871,7 @@ dns_catz_generate_masterfilename(dns_catz_zone_t *zone, dns_catz_entry_t *entry, rlen += strlen(entry->opts.zonedir) + 1; } - result = isc_buffer_reserve(buffer, (unsigned int)rlen); + result = isc_buffer_reserve(*buffer, (unsigned int)rlen); if (result != ISC_R_SUCCESS) { goto cleanup; } @@ -1940,7 +1939,6 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry, */ isc_buffer_allocate(zone->catzs->mctx, &buffer, ISC_BUFFER_INCR); - isc_buffer_setautorealloc(buffer, true); isc_buffer_putstr(buffer, "zone \""); dns_name_totext(&entry->name, true, buffer); isc_buffer_putstr(buffer, "\" { type secondary; primaries"); @@ -1981,7 +1979,7 @@ dns_catz_generate_zonecfg(dns_catz_zone_t *zone, dns_catz_entry_t *entry, } isc_netaddr_fromsockaddr(&netaddr, &entry->opts.masters.addrs[i]); - isc_buffer_reserve(&buffer, INET6_ADDRSTRLEN); + isc_buffer_reserve(buffer, INET6_ADDRSTRLEN); result = isc_netaddr_totext(&netaddr, buffer); RUNTIME_CHECK(result == ISC_R_SUCCESS); diff --git a/lib/dns/dnstap.c b/lib/dns/dnstap.c index 9a03b33593..784acd92f1 100644 --- a/lib/dns/dnstap.c +++ b/lib/dns/dnstap.c @@ -884,7 +884,7 @@ static isc_result_t putstr(isc_buffer_t **b, const char *str) { isc_result_t result; - result = isc_buffer_reserve(b, strlen(str)); + result = isc_buffer_reserve(*b, strlen(str)); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } @@ -1357,7 +1357,7 @@ dns_dt_datatotext(dns_dtdata_t *d, isc_buffer_t **dest) { CHECK(putstr(dest, d->typebuf)); } - CHECK(isc_buffer_reserve(dest, 1)); + CHECK(isc_buffer_reserve(*dest, 1)); isc_buffer_putuint8(*dest, 0); cleanup: diff --git a/lib/dns/keytable.c b/lib/dns/keytable.c index 56dceb2dc1..2e9922509b 100644 --- a/lib/dns/keytable.c +++ b/lib/dns/keytable.c @@ -618,7 +618,7 @@ static isc_result_t putstr(isc_buffer_t **b, const char *str) { isc_result_t result; - result = isc_buffer_reserve(b, strlen(str)); + result = isc_buffer_reserve(*b, strlen(str)); if (result != ISC_R_SUCCESS) { return (result); } diff --git a/lib/dns/nta.c b/lib/dns/nta.c index 44714cfa71..92fb14c535 100644 --- a/lib/dns/nta.c +++ b/lib/dns/nta.c @@ -478,7 +478,7 @@ static isc_result_t putstr(isc_buffer_t **b, const char *str) { isc_result_t result; - result = isc_buffer_reserve(b, strlen(str)); + result = isc_buffer_reserve(*b, strlen(str)); if (result != ISC_R_SUCCESS) { return (result); } diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 295c1d424a..99ad350afe 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -11415,7 +11415,7 @@ dns_resolver_dumpquota(dns_resolver_t *res, isc_buffer_t **buf) { " spilled %" PRIuFAST32 ")", nb, count, allowed, dropped); - result = isc_buffer_reserve(buf, strlen(text)); + result = isc_buffer_reserve(*buf, strlen(text)); if (result != ISC_R_SUCCESS) { goto cleanup; } diff --git a/lib/isc/Makefile.am b/lib/isc/Makefile.am index f44a5a00dd..e3ead9b465 100644 --- a/lib/isc/Makefile.am +++ b/lib/isc/Makefile.am @@ -127,7 +127,6 @@ libisc_la_SOURCES = \ base32.c \ base64.c \ bind9.c \ - buffer.c \ commandline.c \ condition.c \ counter.c \ diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c deleted file mode 100644 index e7e84dff28..0000000000 --- a/lib/isc/buffer.c +++ /dev/null @@ -1,352 +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. - */ - -/*! \file */ - -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -void -isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) { - /* - * Re-initialize the buffer enough to reconfigure the base of the - * buffer. We will swap in the new buffer, after copying any - * data we contain into the new buffer and adjusting all of our - * internal pointers. - * - * The buffer must not be smaller than the length of the original - * buffer. - */ - REQUIRE(b->length <= length); - REQUIRE(base != NULL); - REQUIRE(!b->autore); - - if (b->length > 0U) { - (void)memmove(base, b->base, b->length); - } - - b->base = base; - b->length = length; -} - -void -isc_buffer_setautorealloc(isc_buffer_t *b, bool enable) { - REQUIRE(ISC_BUFFER_VALID(b)); - REQUIRE(b->mctx != NULL); - b->autore = enable; -} - -void -isc_buffer_compact(isc_buffer_t *b) { - unsigned int length; - void *src; - - /* - * Compact the used region by moving the remaining region so it occurs - * at the start of the buffer. The used region is shrunk by the size - * of the consumed region, and the consumed region is then made empty. - */ - - REQUIRE(ISC_BUFFER_VALID(b)); - - src = isc_buffer_current(b); - length = isc_buffer_remaininglength(b); - if (length > 0U) { - (void)memmove(b->base, src, (size_t)length); - } - - if (b->active > b->current) { - b->active -= b->current; - } else { - b->active = 0; - } - b->current = 0; - b->used = length; -} - -uint8_t -isc_buffer_getuint8(isc_buffer_t *b) { - unsigned char *cp; - uint8_t result; - - /* - * Read an unsigned 8-bit integer from 'b' and return it. - */ - - REQUIRE(ISC_BUFFER_VALID(b)); - REQUIRE(b->used - b->current >= 1); - - cp = isc_buffer_current(b); - b->current += 1; - result = ((uint8_t)(cp[0])); - - return (result); -} - -uint16_t -isc_buffer_getuint16(isc_buffer_t *b) { - unsigned char *cp; - uint16_t result; - - /* - * Read an unsigned 16-bit integer in network byte order from 'b', - * convert it to host byte order, and return it. - */ - - REQUIRE(ISC_BUFFER_VALID(b)); - REQUIRE(b->used - b->current >= 2); - - cp = isc_buffer_current(b); - b->current += 2; - result = ((unsigned int)(cp[0])) << 8; - result |= ((unsigned int)(cp[1])); - - return (result); -} - -uint32_t -isc_buffer_getuint32(isc_buffer_t *b) { - unsigned char *cp; - uint32_t result; - - /* - * Read an unsigned 32-bit integer in network byte order from 'b', - * convert it to host byte order, and return it. - */ - - REQUIRE(ISC_BUFFER_VALID(b)); - REQUIRE(b->used - b->current >= 4); - - cp = isc_buffer_current(b); - b->current += 4; - result = ((unsigned int)(cp[0])) << 24; - result |= ((unsigned int)(cp[1])) << 16; - result |= ((unsigned int)(cp[2])) << 8; - result |= ((unsigned int)(cp[3])); - - return (result); -} - -uint64_t -isc_buffer_getuint48(isc_buffer_t *b) { - unsigned char *cp; - uint64_t result; - - /* - * Read an unsigned 48-bit integer in network byte order from 'b', - * convert it to host byte order, and return it. - */ - - REQUIRE(ISC_BUFFER_VALID(b)); - REQUIRE(b->used - b->current >= 6); - - cp = isc_buffer_current(b); - b->current += 6; - result = ((int64_t)(cp[0])) << 40; - result |= ((int64_t)(cp[1])) << 32; - result |= ((int64_t)(cp[2])) << 24; - result |= ((int64_t)(cp[3])) << 16; - result |= ((int64_t)(cp[4])) << 8; - result |= ((int64_t)(cp[5])); - - return (result); -} - -void -isc_buffer_putdecint(isc_buffer_t *b, int64_t v) { - unsigned int l = 0; - unsigned char *cp; - char buf[21]; - isc_result_t result; - - REQUIRE(ISC_BUFFER_VALID(b)); - - /* xxxwpk do it more low-level way ? */ - l = snprintf(buf, 21, "%" PRId64, v); - RUNTIME_CHECK(l <= 21); - if (b->autore) { - result = isc_buffer_reserve(&b, l); - REQUIRE(result == ISC_R_SUCCESS); - } - REQUIRE(isc_buffer_availablelength(b) >= l); - - cp = isc_buffer_used(b); - memmove(cp, buf, l); - b->used += l; -} - -isc_result_t -isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src) { - isc_buffer_t *dst = NULL; - isc_region_t region; - isc_result_t result; - - REQUIRE(dstp != NULL && *dstp == NULL); - REQUIRE(ISC_BUFFER_VALID(src)); - - isc_buffer_usedregion(src, ®ion); - - isc_buffer_allocate(mctx, &dst, region.length); - - result = isc_buffer_copyregion(dst, ®ion); - RUNTIME_CHECK(result == ISC_R_SUCCESS); /* NOSPACE is impossible */ - *dstp = dst; - return (ISC_R_SUCCESS); -} - -isc_result_t -isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) { - isc_result_t result; - - REQUIRE(ISC_BUFFER_VALID(b)); - REQUIRE(r != NULL); - - if (b->autore) { - result = isc_buffer_reserve(&b, r->length); - if (result != ISC_R_SUCCESS) { - return (result); - } - } - - if (r->length > isc_buffer_availablelength(b)) { - return (ISC_R_NOSPACE); - } - - if (r->length > 0U) { - memmove(isc_buffer_used(b), r->base, r->length); - b->used += r->length; - } - - return (ISC_R_SUCCESS); -} - -void -isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, - unsigned int length) { - REQUIRE(dynbuffer != NULL && *dynbuffer == NULL); - - isc_buffer_t *dbuf = isc_mem_get(mctx, sizeof(isc_buffer_t)); - unsigned char *bdata = isc_mem_get(mctx, length); - - isc_buffer_init(dbuf, bdata, length); - - ENSURE(ISC_BUFFER_VALID(dbuf)); - - dbuf->mctx = mctx; - - *dynbuffer = dbuf; -} - -isc_result_t -isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) { - size_t len; - - REQUIRE(dynbuffer != NULL); - REQUIRE(ISC_BUFFER_VALID(*dynbuffer)); - - len = (*dynbuffer)->length; - if ((len - (*dynbuffer)->used) >= size) { - return (ISC_R_SUCCESS); - } - - if ((*dynbuffer)->mctx == NULL) { - return (ISC_R_NOSPACE); - } - - /* Round to nearest buffer size increment */ - len = size + (*dynbuffer)->used; - len = (len + ISC_BUFFER_INCR - 1 - ((len - 1) % ISC_BUFFER_INCR)); - - /* Cap at UINT_MAX */ - if (len > UINT_MAX) { - len = UINT_MAX; - } - - if ((len - (*dynbuffer)->used) < size) { - return (ISC_R_NOMEMORY); - } - - (*dynbuffer)->base = isc_mem_reget((*dynbuffer)->mctx, - (*dynbuffer)->base, - (*dynbuffer)->length, len); - (*dynbuffer)->length = (unsigned int)len; - - return (ISC_R_SUCCESS); -} - -void -isc_buffer_free(isc_buffer_t **dynbuffer) { - isc_buffer_t *dbuf; - isc_mem_t *mctx; - - REQUIRE(dynbuffer != NULL); - REQUIRE(ISC_BUFFER_VALID(*dynbuffer)); - REQUIRE((*dynbuffer)->mctx != NULL); - - dbuf = *dynbuffer; - *dynbuffer = NULL; /* destroy external reference */ - mctx = dbuf->mctx; - dbuf->mctx = NULL; - - isc_mem_put(mctx, dbuf->base, dbuf->length); - isc_buffer_invalidate(dbuf); - isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t)); -} - -isc_result_t -isc_buffer_printf(isc_buffer_t *b, const char *format, ...) { - va_list ap; - int n; - isc_result_t result; - - REQUIRE(ISC_BUFFER_VALID(b)); - - va_start(ap, format); - n = vsnprintf(NULL, 0, format, ap); - va_end(ap); - - if (n < 0) { - return (ISC_R_FAILURE); - } - - if (b->autore) { - result = isc_buffer_reserve(&b, n + 1); - if (result != ISC_R_SUCCESS) { - return (result); - } - } - - if (isc_buffer_availablelength(b) < (unsigned int)n + 1) { - return (ISC_R_NOSPACE); - } - - va_start(ap, format); - n = vsnprintf(isc_buffer_used(b), n + 1, format, ap); - va_end(ap); - - if (n < 0) { - return (ISC_R_FAILURE); - } - - b->used += n; - - return (ISC_R_SUCCESS); -} diff --git a/lib/isc/httpd.c b/lib/isc/httpd.c index 039de4da1a..6cdd5b01ca 100644 --- a/lib/isc/httpd.c +++ b/lib/isc/httpd.c @@ -562,7 +562,6 @@ isc__httpd_sendreq_new(isc_httpd_t *httpd) { */ isc_buffer_allocate(req->mctx, &req->sendbuffer, HTTP_SENDLEN); isc_buffer_clear(req->sendbuffer); - isc_buffer_setautorealloc(req->sendbuffer, true); isc_buffer_initnull(&req->bodybuffer); diff --git a/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h index 1be0081e4c..d9cec44c6b 100644 --- a/lib/isc/include/isc/buffer.h +++ b/lib/isc/include/isc/buffer.h @@ -104,13 +104,16 @@ #include #include +#include #include #include #include #include +#include #include #include #include +#include ISC_LANG_BEGINDECLS @@ -127,7 +130,7 @@ ISC_LANG_BEGINDECLS * space in a buffer, we round the allocated buffer length up to the * nearest * multiple of this value. */ -#define ISC_BUFFER_INCR 2048 +#define ISC_BUFFER_INCR 512 /* * The following macros MUST be used only on valid buffers. It is the @@ -177,21 +180,22 @@ struct isc_buffer { unsigned int current; unsigned int active; /*@}*/ + /*! The extra bytes allocated for static buffer */ + unsigned int extra; + bool dynamic; /*! linkable */ ISC_LINK(isc_buffer_t) link; /*! private internal elements */ isc_mem_t *mctx; - /* automatically realloc buffer at put* */ - bool autore; }; /*** *** Functions ***/ -void -isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, - unsigned int length); +static inline void +isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **restrict dynbuffer, + const unsigned int length); /*!< * \brief Allocate a dynamic linkable buffer which has "length" bytes in the * data region. @@ -205,29 +209,31 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer, *\li Changing the buffer's length field is not permitted. */ -isc_result_t -isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size); +static inline void +isc_buffer_setmctx(isc_buffer_t *restrict b, isc_mem_t *mctx); +static inline void +isc_buffer_clearmctx(isc_buffer_t *restrict b); +/*!< + * \brief Sets/Clears the internal memory context, so isc_buffer_reserve() can + * be used on previously 'static' buffer. + */ + +static inline isc_result_t +isc_buffer_reserve(isc_buffer_t *restrict dynbuffer, const unsigned int size); /*!< * \brief Make "size" bytes of space available in the buffer. The buffer * pointer may move when you call this function. * * Requires: - *\li "dynbuffer" is not NULL. - * - *\li "*dynbuffer" is a valid dynamic buffer. + *\li "dynbuffer" is a valid dynamic buffer. * * Returns: *\li ISC_R_SUCCESS - success *\li ISC_R_NOMEMORY - no memory available - * - * Ensures: - *\li "*dynbuffer" will be valid on return and will contain all the - * original data. However, the buffer pointer may be moved during - * reallocation. */ -void -isc_buffer_free(isc_buffer_t **dynbuffer); +static inline void +isc_buffer_free(isc_buffer_t **restrict dynbuffer); /*!< * \brief Release resources allocated for a dynamic buffer. * @@ -242,11 +248,12 @@ isc_buffer_free(isc_buffer_t **dynbuffer); * isc_buffer_allocate(). */ -void -isc__buffer_initnull(isc_buffer_t *b); +static inline void +isc_buffer_initnull(isc_buffer_t *restrict b); -void -isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length); +static inline void +isc_buffer_reinit(isc_buffer_t *restrict b, void *base, + const unsigned int length); /*!< * \brief Make 'b' refer to the 'length'-byte region starting at base. * Any existing data will be copied. @@ -259,18 +266,10 @@ isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length); * */ -void -isc_buffer_setautorealloc(isc_buffer_t *b, bool enable); -/*!< - * \brief Enable or disable autoreallocation on 'b'. - * - * Requires: - *\li 'b' is a valid dynamic buffer (b->mctx != NULL). - * - */ - -void -isc_buffer_compact(isc_buffer_t *b); +static inline void +isc_buffer_trycompact(isc_buffer_t *restrict b); +static inline void +isc_buffer_compact(isc_buffer_t *restrict b); /*!< * \brief Compact the used region by moving the remaining region so it occurs * at the start of the buffer. The used region is shrunk by the size of @@ -289,106 +288,145 @@ isc_buffer_compact(isc_buffer_t *b); * are those of the remaining region (as it was before the call). */ -uint8_t -isc_buffer_getuint8(isc_buffer_t *b); +static inline isc_result_t +isc_buffer_peekuint8(const isc_buffer_t *restrict b, uint8_t *valp); +static inline uint8_t +isc_buffer_getuint8(isc_buffer_t *restrict b); +static inline void +isc_buffer_putuint8(isc_buffer_t *restrict b, const uint8_t val); /*!< - * \brief Read an unsigned 8-bit integer from 'b' and return it. + * \brief Peek/Read/Write an unsigned 8-bit integer from/to 'b'. * * Requires: * *\li 'b' is a valid buffer. * - *\li The length of the remaining region of 'b' is at least 1. + *\li The length of the available region of 'b' is at least 1 + * or the buffer has autoreallocation enabled. * - * Ensures: + * Ensures (for Read): * *\li The current pointer in 'b' is advanced by 1. * - * Returns: + * Ensures (for Write): * - *\li A 8-bit unsigned integer. + *\li The used pointer in 'b' is advanced by 1. + * + * Returns (for Peek and Read): + * + *\li A 8-bit unsigned integer. (peek and get) */ -uint16_t -isc_buffer_getuint16(isc_buffer_t *b); +static inline isc_result_t +isc_buffer_peekuint16(const isc_buffer_t *restrict b, uint16_t *valp); +static inline uint16_t +isc_buffer_getuint16(isc_buffer_t *restrict b); +static inline void +isc_buffer_putuint16(isc_buffer_t *restrict b, const uint16_t val); /*!< - * \brief Read an unsigned 16-bit integer in network byte order from 'b', - * convert it to host byte order, and return it. + * \brief Peek/Read/Write an unsigned 16-bit integer in network byte order + * from/to 'b', convert it to/from host byte order.. * * Requires: * *\li 'b' is a valid buffer. * - *\li The length of the remaining region of 'b' is at least 2. + *\li The length of the available region of 'b' is at least 2 + * or the buffer has autoreallocation enabled. * - * Ensures: + * Ensures (for Read): * *\li The current pointer in 'b' is advanced by 2. * - * Returns: + * Ensures (for Write): + * + *\li The used pointer in 'b' is advanced by 2. + * + * Returns (for Peek and Read): * *\li A 16-bit unsigned integer. */ -uint32_t -isc_buffer_getuint32(isc_buffer_t *b); +static inline isc_result_t +isc_buffer_peekuint32(const isc_buffer_t *restrict b, uint32_t *restrict valp); +static inline uint32_t +isc_buffer_getuint32(isc_buffer_t *restrict b); +static inline void +isc_buffer_putuint32(isc_buffer_t *restrict b, uint32_t const val); /*!< - * \brief Read an unsigned 32-bit integer in network byte order from 'b', - * convert it to host byte order, and return it. + * \brief Peek/Read/Write an unsigned 32-bit integer in network byte order + * from/to 'b', convert it to/from host byte order. * * Requires: * *\li 'b' is a valid buffer. * - *\li The length of the remaining region of 'b' is at least 4. + *\li The length of the available region of 'b' is at least 4 + * or the buffer has autoreallocation enabled. * - * Ensures: + * Ensures (for Read): * *\li The current pointer in 'b' is advanced by 4. * - * Returns: + * Ensures (for Write): + * + *\li The used pointer in 'b' is advanced by 4. + * + * Returns (for Peek and Read): * *\li A 32-bit unsigned integer. */ -uint64_t -isc_buffer_getuint48(isc_buffer_t *b); +static inline isc_result_t +isc_buffer_peekuint48(const isc_buffer_t *restrict b, uint64_t *valp); +static inline uint64_t +isc_buffer_getuint48(isc_buffer_t *restrict b); +static inline void +isc_buffer_putuint48(isc_buffer_t *restrict b, const uint64_t val); /*!< - * \brief Read an unsigned 48-bit integer in network byte order from 'b', - * convert it to host byte order, and return it. + * \brief Peek/Read/Write an unsigned 48-bit integer in network byte order + * from/to 'b', convert it to/from host byte order. * * Requires: * *\li 'b' is a valid buffer. * - *\li The length of the remaining region of 'b' is at least 6. + *\li The length of the available region of 'b' is at least 6 + * or the buffer has autoreallocation enabled. * - * Ensures: + * Ensures (for Read): * *\li The current pointer in 'b' is advanced by 6. * - * Returns: + * Ensures (for Write): + * + *\li The used pointer in 'b' is advanced by 6. + * + * Returns (for Peek and Read): * *\li A 48-bit unsigned integer (stored in a 64-bit integer). */ -void -isc_buffer_putdecint(isc_buffer_t *b, int64_t v); +static inline void +isc_buffer_putmem(isc_buffer_t *restrict b, const unsigned char *restrict base, + const unsigned int length); /*!< - * \brief Put decimal representation of 'v' in b + * \brief Copy 'length' bytes of memory at 'base' into 'b'. * * Requires: *\li 'b' is a valid buffer. * - *\li The length of the available region of 'b' is at least strlen(dec('v')) + *\li 'base' points to 'length' bytes of valid memory. + * + *\li The length of the available region of 'b' is at least 'length' * or the buffer has autoreallocation enabled. * * Ensures: - *\li The used pointer in 'b' is advanced by strlen(dec('v')). + *\li The used pointer in 'b' is advanced by 'length'. */ -isc_result_t -isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r); +static inline isc_result_t +isc_buffer_copyregion(isc_buffer_t *restrict b, const isc_region_t *restrict r); /*!< * \brief Copy the contents of 'r' into 'b'. * @@ -407,8 +445,9 @@ isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r); * big enough. */ -isc_result_t -isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src); +static inline isc_result_t +isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **restrict dstp, + const isc_buffer_t *restrict src); /*!< * \brief Allocate 'dst' and copy used contents of 'src' into it. * @@ -420,8 +459,8 @@ isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **dstp, const isc_buffer_t *src); *\li ISC_R_SUCCESS */ -isc_result_t -isc_buffer_printf(isc_buffer_t *b, const char *format, ...) +static inline isc_result_t +isc_buffer_printf(isc_buffer_t *restrict b, const char *restrict format, ...) ISC_FORMAT_PRINTF(2, 3); /*!< * \brief Append a formatted string to the used region of 'b'. @@ -485,13 +524,16 @@ isc_buffer_printf(isc_buffer_t *b, const char *format, ...) *\li 'base' is a pointer to a sequence of 'length' bytes. */ static inline void -isc_buffer_init(isc_buffer_t *b, void *base, unsigned int length) { - ISC_REQUIRE(b != NULL); +isc_buffer_init(isc_buffer_t *restrict b, void *base, + const unsigned int length) { + REQUIRE(b != NULL); - *b = (isc_buffer_t){ .base = base, - .length = length, - .magic = ISC_BUFFER_MAGIC }; - ISC_LINK_INIT(b, link); + *b = (isc_buffer_t){ + .base = base, + .length = length, + .link = ISC_LINK_INITIALIZER, + .magic = ISC_BUFFER_MAGIC, + }; } /*! @@ -499,9 +541,11 @@ isc_buffer_init(isc_buffer_t *b, void *base, unsigned int length) { * This can later be grown as needed and swapped in place. */ static inline void -isc_buffer_initnull(isc_buffer_t *b) { - *b = (isc_buffer_t){ .magic = ISC_BUFFER_MAGIC }; - ISC_LINK_INIT(b, link); +isc_buffer_initnull(isc_buffer_t *restrict b) { + *b = (isc_buffer_t){ + .link = ISC_LINK_INITIALIZER, + .magic = ISC_BUFFER_MAGIC, + }; } /*! @@ -534,17 +578,14 @@ isc_buffer_initnull(isc_buffer_t *b) { * it will cause an assertion failure. */ static inline void -isc_buffer_invalidate(isc_buffer_t *b) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(!ISC_LINK_LINKED(b, link)); - ISC_REQUIRE(b->mctx == NULL); +isc_buffer_invalidate(isc_buffer_t *restrict b) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(!ISC_LINK_LINKED(b, link)); + REQUIRE(b->mctx == NULL); - b->magic = 0; - b->base = NULL; - b->length = 0; - b->used = 0; - b->current = 0; - b->active = 0; + *b = (isc_buffer_t){ + .magic = 0, + }; } /*! @@ -557,9 +598,9 @@ isc_buffer_invalidate(isc_buffer_t *b) { *\li 'r' points to a region structure. */ static inline void -isc_buffer_region(isc_buffer_t *b, isc_region_t *r) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(r != NULL); +isc_buffer_region(isc_buffer_t *restrict b, isc_region_t *restrict r) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(r != NULL); r->base = b->base; r->length = b->length; @@ -575,9 +616,10 @@ isc_buffer_region(isc_buffer_t *b, isc_region_t *r) { *\li 'r' points to a region structure. */ static inline void -isc_buffer_usedregion(const isc_buffer_t *b, isc_region_t *r) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(r != NULL); +isc_buffer_usedregion(const isc_buffer_t *restrict b, + isc_region_t *restrict r) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(r != NULL); r->base = b->base; r->length = b->used; @@ -593,9 +635,9 @@ isc_buffer_usedregion(const isc_buffer_t *b, isc_region_t *r) { *\li 'r' points to a region structure. */ static inline void -isc_buffer_availableregion(isc_buffer_t *b, isc_region_t *r) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(r != NULL); +isc_buffer_availableregion(isc_buffer_t *restrict b, isc_region_t *restrict r) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(r != NULL); r->base = isc_buffer_used(b); r->length = isc_buffer_availablelength(b); @@ -611,9 +653,9 @@ isc_buffer_availableregion(isc_buffer_t *b, isc_region_t *r) { *\li used + n <= length */ static inline void -isc_buffer_add(isc_buffer_t *b, unsigned int n) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(b->used + n <= b->length); +isc_buffer_add(isc_buffer_t *restrict b, const unsigned int n) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(b->used + n <= b->length); b->used += n; } @@ -628,9 +670,9 @@ isc_buffer_add(isc_buffer_t *b, unsigned int n) { *\li used >= n */ static inline void -isc_buffer_subtract(isc_buffer_t *b, unsigned int n) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(b->used >= n); +isc_buffer_subtract(isc_buffer_t *restrict b, const unsigned int n) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(b->used >= n); b->used -= n; if (b->current > b->used) { @@ -653,8 +695,8 @@ isc_buffer_subtract(isc_buffer_t *b, unsigned int n) { *\li used = 0 */ static inline void -isc_buffer_clear(isc_buffer_t *b) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); +isc_buffer_clear(isc_buffer_t *restrict b) { + REQUIRE(ISC_BUFFER_VALID(b)); b->used = 0; b->current = 0; @@ -671,9 +713,9 @@ isc_buffer_clear(isc_buffer_t *b) { *\li 'r' points to a region structure. */ static inline void -isc_buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(r != NULL); +isc_buffer_consumedregion(isc_buffer_t *restrict b, isc_region_t *restrict r) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(r != NULL); r->base = b->base; r->length = b->current; @@ -689,9 +731,9 @@ isc_buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) { *\li 'r' points to a region structure. */ static inline void -isc_buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(r != NULL); +isc_buffer_remainingregion(isc_buffer_t *restrict b, isc_region_t *restrict r) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(r != NULL); r->base = isc_buffer_current(b); r->length = isc_buffer_remaininglength(b); @@ -707,9 +749,9 @@ isc_buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) { *\li 'r' points to a region structure. */ static inline void -isc_buffer_activeregion(isc_buffer_t *b, isc_region_t *r) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(r != NULL); +isc_buffer_activeregion(isc_buffer_t *restrict b, isc_region_t *restrict r) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(r != NULL); if (b->current < b->active) { r->base = isc_buffer_current(b); @@ -730,9 +772,9 @@ isc_buffer_activeregion(isc_buffer_t *b, isc_region_t *r) { *\li current + n <= used */ static inline void -isc_buffer_setactive(isc_buffer_t *b, unsigned int n) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(b->current + n <= b->used); +isc_buffer_setactive(isc_buffer_t *restrict b, const unsigned int n) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(b->current + n <= b->used); b->active = b->current + n; } @@ -749,8 +791,8 @@ isc_buffer_setactive(isc_buffer_t *b, unsigned int n) { *\li current == 0 */ static inline void -isc_buffer_first(isc_buffer_t *b) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); +isc_buffer_first(isc_buffer_t *restrict b) { + REQUIRE(ISC_BUFFER_VALID(b)); b->current = 0; } @@ -765,9 +807,9 @@ isc_buffer_first(isc_buffer_t *b) { *\li current + n <= used */ static inline void -isc_buffer_forward(isc_buffer_t *b, unsigned int n) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(b->current + n <= b->used); +isc_buffer_forward(isc_buffer_t *restrict b, const unsigned int n) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(b->current + n <= b->used); b->current += n; } @@ -782,203 +824,166 @@ isc_buffer_forward(isc_buffer_t *b, unsigned int n) { *\li n <= current */ static inline void -isc_buffer_back(isc_buffer_t *b, unsigned int n) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(n <= b->current); +isc_buffer_back(isc_buffer_t *restrict b, const unsigned int n) { + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(n <= b->current); b->current -= n; } -/*! - * \brief Store an unsigned 8-bit integer from 'val' into 'b'. - * - * Requires: - *\li 'b' is a valid buffer. - * - *\li The length of the available region of 'b' is at least 1 - * or the buffer has autoreallocation enabled. - * - * Ensures: - *\li The used pointer in 'b' is advanced by 1. - */ -static inline void -isc_buffer_putuint8(isc_buffer_t *b, uint8_t val) { - unsigned char *cp; - - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - - if (b->autore) { - isc_buffer_t *tmp = b; - ISC_REQUIRE(isc_buffer_reserve(&tmp, 1) == ISC_R_SUCCESS); +#define ISC_BUFFER_PEEK_CHECK(b, s) \ + { \ + REQUIRE(ISC_BUFFER_VALID(b)); \ + if ((b)->used - (b)->current < s) { \ + return (ISC_R_NOMORE); \ + } \ } - ISC_REQUIRE(isc_buffer_availablelength(b) >= 1U); +static inline isc_result_t +isc_buffer_peekuint8(const isc_buffer_t *restrict b, uint8_t *valp) { + ISC_BUFFER_PEEK_CHECK(b, sizeof(*valp)); - cp = isc_buffer_used(b); - b->used++; + uint8_t *cp = isc_buffer_current(b); + if (valp != NULL) { + *valp = (uint8_t)(cp[0]); + } + return (ISC_R_SUCCESS); +} + +static inline uint8_t +isc_buffer_getuint8(isc_buffer_t *restrict b) { + uint8_t val = 0; + isc_result_t result = isc_buffer_peekuint8(b, &val); + ENSURE(result == ISC_R_SUCCESS); + b->current += sizeof(val); + return (val); +} + +#define ISC_BUFFER_PUT_RESERVE(b, v) \ + { \ + REQUIRE(ISC_BUFFER_VALID(b)); \ + \ + if (b->mctx) { \ + isc_result_t result = isc_buffer_reserve(b, \ + sizeof(val)); \ + ENSURE(result == ISC_R_SUCCESS); \ + } \ + \ + REQUIRE(isc_buffer_availablelength(b) >= sizeof(val)); \ + } + +static inline void +isc_buffer_putuint8(isc_buffer_t *restrict b, const uint8_t val) { + ISC_BUFFER_PUT_RESERVE(b, val); + + uint8_t *cp = isc_buffer_used(b); + b->used += sizeof(val); cp[0] = val; } -/*! - * \brief Store an unsigned 16-bit integer in host byte order from 'val' - * into 'b' in network byte order. - * - * Requires: - *\li 'b' is a valid buffer. - * - *\li The length of the available region of 'b' is at least 2 - * or the buffer has autoreallocation enabled. - * - * Ensures: - *\li The used pointer in 'b' is advanced by 2. - */ -static inline void -isc_buffer_putuint16(isc_buffer_t *b, uint16_t val) { - unsigned char *cp; +static inline isc_result_t +isc_buffer_peekuint16(const isc_buffer_t *restrict b, uint16_t *valp) { + ISC_BUFFER_PEEK_CHECK(b, sizeof(*valp)); - ISC_REQUIRE(ISC_BUFFER_VALID(b)); + uint8_t *cp = isc_buffer_current(b); - if (b->autore) { - isc_buffer_t *tmp = b; - ISC_REQUIRE(isc_buffer_reserve(&tmp, 2) == ISC_R_SUCCESS); + if (valp != NULL) { + *valp = ISC_U8TO16_BE(cp); } - - ISC_REQUIRE(isc_buffer_availablelength(b) >= 2U); - - cp = isc_buffer_used(b); - b->used += 2; - cp[0] = (unsigned char)(val >> 8); - cp[1] = (unsigned char)val; + return (ISC_R_SUCCESS); } -/*! - * Store an unsigned 24-bit integer in host byte order from 'val' - * into 'b' in network byte order. - * - * Requires: - *\li 'b' is a valid buffer. - * - *\li The length of the available region of 'b' is at least 3 - * or the buffer has autoreallocation enabled. - * - * Ensures: - *\li The used pointer in 'b' is advanced by 3. - */ -static inline void -isc_buffer_putuint24(isc_buffer_t *b, uint32_t val) { - unsigned char *cp; - - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - - if (b->autore) { - isc_buffer_t *tmp = b; - ISC_REQUIRE(isc_buffer_reserve(&tmp, 3) == ISC_R_SUCCESS); - } - - ISC_REQUIRE(isc_buffer_availablelength(b) >= 3U); - - cp = isc_buffer_used(b); - b->used += 3; - cp[0] = (unsigned char)(val >> 16); - cp[1] = (unsigned char)(val >> 8); - cp[2] = (unsigned char)val; +static inline uint16_t +isc_buffer_getuint16(isc_buffer_t *restrict b) { + uint16_t val = 0; + isc_result_t result = isc_buffer_peekuint16(b, &val); + ENSURE(result == ISC_R_SUCCESS); + b->current += sizeof(val); + return (val); } -/*! - * \brief Store an unsigned 32-bit integer in host byte order from 'val' - * into 'b' in network byte order. - * - * Requires: - *\li 'b' is a valid buffer. - * - *\li The length of the available region of 'b' is at least 4 - * or the buffer has autoreallocation enabled. - * - * Ensures: - *\li The used pointer in 'b' is advanced by 4. - */ static inline void -isc_buffer_putuint32(isc_buffer_t *b, uint32_t val) { - unsigned char *cp; +isc_buffer_putuint16(isc_buffer_t *restrict b, const uint16_t val) { + ISC_BUFFER_PUT_RESERVE(b, val); - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - - if (b->autore) { - isc_buffer_t *tmp = b; - ISC_REQUIRE(isc_buffer_reserve(&tmp, 4) == ISC_R_SUCCESS); - } - - ISC_REQUIRE(isc_buffer_availablelength(b) >= 4U); - - cp = isc_buffer_used(b); - b->used += 4; - cp[0] = (unsigned char)(val >> 24); - cp[1] = (unsigned char)(val >> 16); - cp[2] = (unsigned char)(val >> 8); - cp[3] = (unsigned char)val; + uint8_t *cp = isc_buffer_used(b); + b->used += sizeof(val); + ISC_U16TO8_BE(cp, val); } -/*! - * \brief Store an unsigned 48-bit integer in host byte order from 'val' - * into 'b' in network byte order. - * - * Requires: - *\li 'b' is a valid buffer. - * - *\li The length of the available region of 'b' is at least 6 - * or the buffer has autoreallocation enabled. - * - * Ensures: - *\li The used pointer in 'b' is advanced by 6. - */ -static inline void -isc_buffer_putuint48(isc_buffer_t *b, uint64_t val) { - unsigned char *cp = NULL; +static inline isc_result_t +isc_buffer_peekuint32(const isc_buffer_t *restrict b, uint32_t *valp) { + ISC_BUFFER_PEEK_CHECK(b, sizeof(*valp)); - ISC_REQUIRE(ISC_BUFFER_VALID(b)); + uint8_t *cp = isc_buffer_current(b); - if (b->autore) { - isc_buffer_t *tmp = b; - ISC_REQUIRE(isc_buffer_reserve(&tmp, 6) == ISC_R_SUCCESS); + if (valp != NULL) { + *valp = ISC_U8TO32_BE(cp); } + return (ISC_R_SUCCESS); +} - ISC_REQUIRE(isc_buffer_availablelength(b) >= 6U); +uint32_t +isc_buffer_getuint32(isc_buffer_t *restrict b) { + uint32_t val = 0; + isc_result_t result = isc_buffer_peekuint32(b, &val); + ENSURE(result == ISC_R_SUCCESS); + b->current += sizeof(val); + return (val); +} - cp = isc_buffer_used(b); +static inline void +isc_buffer_putuint32(isc_buffer_t *restrict b, const uint32_t val) { + ISC_BUFFER_PUT_RESERVE(b, val); + + uint8_t *cp = isc_buffer_used(b); + b->used += sizeof(val); + + ISC_U32TO8_BE(cp, val); +} + +static inline isc_result_t +isc_buffer_peekuint48(const isc_buffer_t *restrict b, uint64_t *valp) { + ISC_BUFFER_PEEK_CHECK(b, 6); /* 48-bits */ + + uint8_t *cp = isc_buffer_current(b); + + if (valp != NULL) { + *valp = ISC_U8TO48_BE(cp); + } + return (ISC_R_SUCCESS); +} + +static inline uint64_t +isc_buffer_getuint48(isc_buffer_t *restrict b) { + uint64_t val = 0; + isc_result_t result = isc_buffer_peekuint48(b, &val); + ENSURE(result == ISC_R_SUCCESS); + b->current += 6; /* 48-bits */ + return (val); +} + +static inline void +isc_buffer_putuint48(isc_buffer_t *restrict b, const uint64_t val) { + ISC_BUFFER_PUT_RESERVE(b, val); + + uint8_t *cp = isc_buffer_used(b); b->used += 6; - cp[0] = (unsigned char)(val >> 40); - cp[1] = (unsigned char)(val >> 32); - cp[2] = (unsigned char)(val >> 24); - cp[3] = (unsigned char)(val >> 16); - cp[4] = (unsigned char)(val >> 8); - cp[5] = (unsigned char)val; + + ISC_U48TO8_BE(cp, val); } -/*! - * \brief Copy 'length' bytes of memory at 'base' into 'b'. - * - * Requires: - *\li 'b' is a valid buffer. - * - *\li 'base' points to 'length' bytes of valid memory. - * - *\li The length of the available region of 'b' is at least 'length' - * or the buffer has autoreallocation enabled. - * - * Ensures: - *\li The used pointer in 'b' is advanced by 'length'. - */ static inline void -isc_buffer_putmem(isc_buffer_t *b, const unsigned char *base, - unsigned int length) { - ISC_REQUIRE(ISC_BUFFER_VALID(b)); +isc_buffer_putmem(isc_buffer_t *restrict b, const unsigned char *restrict base, + const unsigned int length) { + REQUIRE(ISC_BUFFER_VALID(b)); - if (b->autore) { - isc_buffer_t *tmp = b; - ISC_REQUIRE(isc_buffer_reserve(&tmp, length) == ISC_R_SUCCESS); + if (b->mctx) { + isc_result_t result = isc_buffer_reserve(b, length); + REQUIRE(result == ISC_R_SUCCESS); } - ISC_REQUIRE(isc_buffer_availablelength(b) >= (unsigned int)length); + REQUIRE(isc_buffer_availablelength(b) >= (unsigned int)length); if (length > 0U) { memmove(isc_buffer_used(b), base, length); @@ -1001,23 +1006,263 @@ isc_buffer_putmem(isc_buffer_t *b, const unsigned char *base, *\li The used pointer in 'b' is advanced by strlen('source'). */ static inline void -isc_buffer_putstr(isc_buffer_t *b, const char *source) { +isc_buffer_putstr(isc_buffer_t *restrict b, const char *restrict source) { unsigned int length; unsigned char *cp; - ISC_REQUIRE(ISC_BUFFER_VALID(b)); - ISC_REQUIRE(source != NULL); + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(source != NULL); length = (unsigned int)strlen(source); - if (b->autore) { - isc_buffer_t *tmp = b; - ISC_REQUIRE(isc_buffer_reserve(&tmp, length) == ISC_R_SUCCESS); + if (b->mctx) { + isc_result_t result = isc_buffer_reserve(b, length); + ENSURE(result == ISC_R_SUCCESS); } - ISC_REQUIRE(isc_buffer_availablelength(b) >= length); + REQUIRE(isc_buffer_availablelength(b) >= length); cp = isc_buffer_used(b); memmove(cp, source, length); b->used += length; } + +static inline void +isc_buffer_reinit(isc_buffer_t *restrict b, void *base, + const unsigned int length) { + /* + * Re-initialize the buffer enough to reconfigure the base of the + * buffer. We will swap in the new buffer, after copying any + * data we contain into the new buffer and adjusting all of our + * internal pointers. + * + * The buffer must not be smaller than the length of the original + * buffer. + */ + REQUIRE(b->length <= length); + REQUIRE(base != NULL); + REQUIRE(b->mctx == NULL); + + if (b->length > 0U) { + (void)memmove(base, b->base, b->length); + } + + b->base = base; + b->length = length; +} + +static inline void +isc_buffer_trycompact(isc_buffer_t *restrict b) { + if (isc_buffer_consumedlength(b) >= isc_buffer_remaininglength(b)) { + isc_buffer_compact(b); + } +} + +static inline void +isc_buffer_compact(isc_buffer_t *restrict b) { + unsigned int length; + void *src; + + /* + * Compact the used region by moving the remaining region so it occurs + * at the start of the buffer. The used region is shrunk by the size + * of the consumed region, and the consumed region is then made empty. + */ + + REQUIRE(ISC_BUFFER_VALID(b)); + + src = isc_buffer_current(b); + length = isc_buffer_remaininglength(b); + if (length > 0U) { + (void)memmove(b->base, src, (size_t)length); + } + + if (b->active > b->current) { + b->active -= b->current; + } else { + b->active = 0; + } + b->current = 0; + b->used = length; +} + +static inline void +isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **restrict dbufp, + const unsigned int length) { + REQUIRE(dbufp != NULL && *dbufp == NULL); + + isc_buffer_t *dbuf = isc_mem_get(mctx, sizeof(*dbuf) + length); + uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf); + + isc_buffer_init(dbuf, bdata, length); + dbuf->extra = length; + isc_buffer_setmctx(dbuf, mctx); + + *dbufp = dbuf; +} + +static inline void +isc_buffer_setmctx(isc_buffer_t *restrict b, isc_mem_t *mctx) { + REQUIRE(ISC_BUFFER_VALID(b)); + + b->mctx = mctx; +} + +static inline void +isc_buffer_clearmctx(isc_buffer_t *restrict b) { + REQUIRE(ISC_BUFFER_VALID(b)); + + if (b->dynamic) { + isc_mem_put(b->mctx, b->base, b->length); + b->dynamic = false; + } + + b->mctx = NULL; +} + +static inline isc_result_t +isc_buffer_reserve(isc_buffer_t *restrict dbuf, const unsigned int size) { + REQUIRE(ISC_BUFFER_VALID(dbuf)); + + size_t len; + + len = dbuf->length; + if ((len - dbuf->used) >= size) { + return (ISC_R_SUCCESS); + } + + if (dbuf->mctx == NULL) { + return (ISC_R_NOSPACE); + } + + /* Round to nearest buffer size increment */ + len = size + dbuf->used; + len = ISC_ALIGN(len, ISC_BUFFER_INCR); + + /* Cap at UINT_MAX */ + if (len > UINT_MAX) { + len = UINT_MAX; + } + + if ((len - dbuf->used) < size) { + return (ISC_R_NOMEMORY); + } + + if (!dbuf->dynamic) { + void *old_base = dbuf->base; + dbuf->base = isc_mem_get(dbuf->mctx, len); + memmove(dbuf->base, old_base, dbuf->used); + dbuf->dynamic = true; + } else { + dbuf->base = isc_mem_reget(dbuf->mctx, dbuf->base, dbuf->length, + len); + } + dbuf->length = (unsigned int)len; + + return (ISC_R_SUCCESS); +} + +static inline void +isc_buffer_free(isc_buffer_t **restrict dbufp) { + REQUIRE(dbufp != NULL && ISC_BUFFER_VALID(*dbufp)); + REQUIRE((*dbufp)->mctx != NULL); + + isc_buffer_t *dbuf = *dbufp; + isc_mem_t *mctx = dbuf->mctx; + unsigned int extra = dbuf->extra; + + *dbufp = NULL; /* destroy external reference */ + + isc_buffer_clearmctx(dbuf); + + isc_buffer_invalidate(dbuf); + isc_mem_put(mctx, dbuf, sizeof(*dbuf) + extra); +} + +static inline isc_result_t +isc_buffer_dup(isc_mem_t *mctx, isc_buffer_t **restrict dstp, + const isc_buffer_t *restrict src) { + isc_buffer_t *dst = NULL; + isc_region_t region; + isc_result_t result; + + REQUIRE(dstp != NULL && *dstp == NULL); + REQUIRE(ISC_BUFFER_VALID(src)); + + isc_buffer_usedregion(src, ®ion); + + isc_buffer_allocate(mctx, &dst, region.length); + + result = isc_buffer_copyregion(dst, ®ion); + RUNTIME_CHECK(result == ISC_R_SUCCESS); /* NOSPACE is impossible */ + *dstp = dst; + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +isc_buffer_copyregion(isc_buffer_t *restrict b, + const isc_region_t *restrict r) { + isc_result_t result; + + REQUIRE(ISC_BUFFER_VALID(b)); + REQUIRE(r != NULL); + + if (b->mctx) { + result = isc_buffer_reserve(b, r->length); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + if (r->length > isc_buffer_availablelength(b)) { + return (ISC_R_NOSPACE); + } + + if (r->length > 0U) { + memmove(isc_buffer_used(b), r->base, r->length); + b->used += r->length; + } + + return (ISC_R_SUCCESS); +} + +static inline isc_result_t +isc_buffer_printf(isc_buffer_t *restrict b, const char *restrict format, ...) { + va_list ap; + int n; + isc_result_t result; + + REQUIRE(ISC_BUFFER_VALID(b)); + + va_start(ap, format); + n = vsnprintf(NULL, 0, format, ap); + va_end(ap); + + if (n < 0) { + return (ISC_R_FAILURE); + } + + if (b->mctx) { + result = isc_buffer_reserve(b, n + 1); + if (result != ISC_R_SUCCESS) { + return (result); + } + } + + if (isc_buffer_availablelength(b) < (unsigned int)n + 1) { + return (ISC_R_NOSPACE); + } + + va_start(ap, format); + n = vsnprintf(isc_buffer_used(b), n + 1, format, ap); + va_end(ap); + + if (n < 0) { + return (ISC_R_FAILURE); + } + + b->used += n; + + return (ISC_R_SUCCESS); +} + ISC_LANG_ENDDECLS diff --git a/lib/isc/include/isc/endian.h b/lib/isc/include/isc/endian.h index be91b1dcfa..6d5e6c2b4f 100644 --- a/lib/isc/include/isc/endian.h +++ b/lib/isc/include/isc/endian.h @@ -164,3 +164,101 @@ #endif /* WORDS_BIGENDIAN */ #endif /* !htobe64 */ + +/* + * Macros to convert uint8_t arrays to integers. + */ + +/* Low-Endian */ + +#define ISC_U16TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); + +#define ISC_U8TO16_LE(p) (((uint16_t)((p)[0])) | ((uint16_t)((p)[1]) << 8)) + +#define ISC_U32TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); + +#define ISC_U8TO32_LE(p) \ + (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) + +#define ISC_U48TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); \ + (p)[4] = (uint8_t)((v) >> 32); \ + (p)[5] = (uint8_t)((v) >> 40); + +#define ISC_U8TO48_LE(p) \ + (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ + ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ + ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40)) + +#define ISC_U64TO8_LE(p, v) \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); \ + (p)[4] = (uint8_t)((v) >> 32); \ + (p)[5] = (uint8_t)((v) >> 40); \ + (p)[6] = (uint8_t)((v) >> 48); \ + (p)[7] = (uint8_t)((v) >> 56); + +#define ISC_U8TO64_LE(p) \ + (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ + ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ + ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ + ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) + +/* Big-Endian */ + +#define ISC_U16TO8_BE(p, v) \ + (p)[0] = (uint8_t)((v) >> 8); \ + (p)[1] = (uint8_t)((v)); + +#define ISC_U8TO16_BE(p) (((uint16_t)((p)[0]) << 8) | ((uint16_t)((p)[1]))) + +#define ISC_U32TO8_BE(p, v) \ + (p)[0] = (uint8_t)((v) >> 24); \ + (p)[1] = (uint8_t)((v) >> 16); \ + (p)[2] = (uint8_t)((v) >> 8); \ + (p)[3] = (uint8_t)((v)); + +#define ISC_U8TO32_BE(p) \ + (((uint32_t)((p)[0]) << 24) | ((uint32_t)((p)[1]) << 16) | \ + ((uint32_t)((p)[2]) << 8) | ((uint32_t)((p)[3]))) + +#define ISC_U48TO8_BE(p, v) \ + (p)[0] = (uint8_t)((v) >> 40); \ + (p)[1] = (uint8_t)((v) >> 32); \ + (p)[2] = (uint8_t)((v) >> 24); \ + (p)[3] = (uint8_t)((v) >> 16); \ + (p)[4] = (uint8_t)((v) >> 8); \ + (p)[5] = (uint8_t)((v)); + +#define ISC_U8TO48_BE(p) \ + (((uint64_t)((p)[0]) << 40) | ((uint64_t)((p)[1]) << 32) | \ + ((uint64_t)((p)[2]) << 24) | ((uint64_t)((p)[3]) << 16) | \ + ((uint64_t)((p)[4]) << 8) | ((uint64_t)((p)[5]))) + +#define ISC_U64TO8_BE(p, v) \ + (p)[0] = (uint8_t)((v) >> 56); \ + (p)[1] = (uint8_t)((v) >> 48); \ + (p)[2] = (uint8_t)((v) >> 40); \ + (p)[3] = (uint8_t)((v) >> 32); \ + (p)[4] = (uint8_t)((v) >> 24); \ + (p)[5] = (uint8_t)((v) >> 16); \ + (p)[6] = (uint8_t)((v) >> 8); \ + (p)[7] = (uint8_t)((v)); + +#define ISC_U8TO64_BE(p) \ + (((uint64_t)((p)[0]) << 56) | ((uint64_t)((p)[1]) << 48) | \ + ((uint64_t)((p)[2]) << 40) | ((uint64_t)((p)[3]) << 32) | \ + ((uint64_t)((p)[4]) << 24) | ((uint64_t)((p)[5]) << 16) | \ + ((uint64_t)((p)[6]) << 8) | ((uint64_t)((p)[7]))) diff --git a/lib/isc/netmgr/http.c b/lib/isc/netmgr/http.c index cf04ac3d46..7cb69b5f97 100644 --- a/lib/isc/netmgr/http.c +++ b/lib/isc/netmgr/http.c @@ -443,7 +443,6 @@ new_http_cstream(isc_nmsocket_t *sock, http_cstream_t **streamp) { isc_buffer_allocate(mctx, &stream->rbuf, INITIAL_DNS_MESSAGE_BUFFER_SIZE); - isc_buffer_setautorealloc(stream->rbuf, true); ISC_LIST_PREPEND(sock->h2.session->cstreams, stream, link); *streamp = stream; @@ -1005,7 +1004,6 @@ http_readcb(isc_nmhandle_t *handle, isc_result_t result, isc_region_t *region, if (session->buf == NULL) { isc_buffer_allocate(session->mctx, &session->buf, unread_size); - isc_buffer_setautorealloc(session->buf, true); } isc_buffer_putmem(session->buf, region->base + readlen, unread_size); @@ -1121,8 +1119,6 @@ http_send_outgoing(isc_nm_http_session_t *session, isc_nmhandle_t *httphandle, isc_buffer_allocate(session->mctx, &session->pending_write_data, INITIAL_DNS_MESSAGE_BUFFER_SIZE); - isc_buffer_setautorealloc(session->pending_write_data, - true); } isc_buffer_putmem(session->pending_write_data, data, pending); total = new_total; @@ -1267,13 +1263,15 @@ http_do_bio(isc_nm_http_session_t *session, isc_nmhandle_t *send_httphandle, if (nghttp2_session_want_read(session->ngsession) != 0) { if (!session->reading) { - /* We have not yet started reading from this handle */ + /* We have not yet started + * reading from this handle */ isc_nm_read(session->handle, http_readcb, session); session->reading = true; } else if (session->buf != NULL) { size_t remaining = isc_buffer_remaininglength(session->buf); - /* Leftover data in the buffer, use it */ + /* Leftover data in the + * buffer, use it */ size_t readlen = nghttp2_session_mem_recv( session->ngsession, isc_buffer_current(session->buf), remaining); @@ -1288,7 +1286,9 @@ http_do_bio(isc_nm_http_session_t *session, isc_nmhandle_t *send_httphandle, send_cbarg); return; } else { - /* Resume reading, it's idempotent, wait for more */ + /* Resume reading, it's + * idempotent, wait for more + */ isc_nm_read(session->handle, http_readcb, session); } } else { @@ -1406,9 +1406,10 @@ transport_connect_cb(isc_nmhandle_t *handle, isc_result_t result, void *cbarg) { NGHTTP2_PROTO_VERSION_ID_LEN) != 0) { /* - * HTTP/2 negotiation error. Any sensible DoH - * client will fail if HTTP/2 cannot be - * negotiated via ALPN. + * HTTP/2 negotiation error. + * Any sensible DoH client + * will fail if HTTP/2 cannot + * be negotiated via ALPN. */ result = ISC_R_HTTP2ALPNERROR; goto error; @@ -2346,9 +2347,12 @@ server_on_frame_recv_callback(nghttp2_session *ngsession, ngsession, frame->hd.stream_id); /* - * For DATA and HEADERS frame, this callback may be - * called after on_stream_close_callback. Check that - * the stream is still alive. + * For DATA and HEADERS frame, + * this callback may be called + * after + * on_stream_close_callback. + * Check that the stream is + * still alive. */ if (socket == NULL) { return (0); @@ -3168,9 +3172,12 @@ isc__nm_base64_to_base64url(isc_mem_t *mem, const char *base64, break; default: /* - * All other characters from the alphabet are the same - * for both base64 and base64url, so we can reuse the - * validation table for the rest of the characters. + * All other characters from + * the alphabet are the same + * for both base64 and + * base64url, so we can reuse + * the validation table for + * the rest of the characters. */ if (base64[i] != '-' && base64[i] != '_' && base64url_validation_table[(size_t)base64[i]]) diff --git a/lib/isc/siphash.c b/lib/isc/siphash.c index 8d13c61243..179e9f31a8 100644 --- a/lib/isc/siphash.c +++ b/lib/isc/siphash.c @@ -67,29 +67,9 @@ #define HALFSIPROUND FULL_ROUND32 -#define U32TO8_LE(p, v) \ - (p)[0] = (uint8_t)((v)); \ - (p)[1] = (uint8_t)((v) >> 8); \ - (p)[2] = (uint8_t)((v) >> 16); \ - (p)[3] = (uint8_t)((v) >> 24); - -#define U8TO32_LE(p) \ - (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \ - ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) - #define U8TO32_ONE(case_sensitive, byte) \ (uint32_t)(case_sensitive ? byte : isc__ascii_tolower1(byte)) -#define U64TO8_LE(p, v) \ - U32TO8_LE((p), (uint32_t)((v))); \ - U32TO8_LE((p) + 4, (uint32_t)((v) >> 32)); - -#define U8TO64_LE(p) \ - (((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \ - ((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \ - ((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \ - ((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56)) - #define U8TO64_ONE(case_sensitive, byte) \ (uint64_t)(case_sensitive ? byte : isc__ascii_tolower1(byte)) @@ -99,8 +79,8 @@ isc_siphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, REQUIRE(k != NULL); REQUIRE(out != NULL); - uint64_t k0 = U8TO64_LE(k); - uint64_t k1 = U8TO64_LE(k + 8); + uint64_t k0 = ISC_U8TO64_LE(k); + uint64_t k1 = ISC_U8TO64_LE(k + 8); uint64_t v0 = UINT64_C(0x736f6d6570736575) ^ k0; uint64_t v1 = UINT64_C(0x646f72616e646f6d) ^ k1; @@ -113,8 +93,9 @@ isc_siphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, const size_t left = inlen & 7; for (; in != end; in += 8) { - uint64_t m = case_sensitive ? U8TO64_LE(in) - : isc_ascii_tolower8(U8TO64_LE(in)); + uint64_t m = case_sensitive + ? ISC_U8TO64_LE(in) + : isc_ascii_tolower8(ISC_U8TO64_LE(in)); v3 ^= m; @@ -169,7 +150,7 @@ isc_siphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, b = v0 ^ v1 ^ v2 ^ v3; - U64TO8_LE(out, b); + ISC_U64TO8_LE(out, b); } void @@ -178,8 +159,8 @@ isc_halfsiphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, REQUIRE(k != NULL); REQUIRE(out != NULL); - uint32_t k0 = U8TO32_LE(k); - uint32_t k1 = U8TO32_LE(k + 4); + uint32_t k0 = ISC_U8TO32_LE(k); + uint32_t k1 = ISC_U8TO32_LE(k + 4); uint32_t v0 = UINT32_C(0x00000000) ^ k0; uint32_t v1 = UINT32_C(0x00000000) ^ k1; @@ -192,8 +173,9 @@ isc_halfsiphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, const int left = inlen & 3; for (; in != end; in += 4) { - uint32_t m = case_sensitive ? U8TO32_LE(in) - : isc_ascii_tolower4(U8TO32_LE(in)); + uint32_t m = case_sensitive + ? ISC_U8TO32_LE(in) + : isc_ascii_tolower4(ISC_U8TO32_LE(in)); v3 ^= m; @@ -235,5 +217,5 @@ isc_halfsiphash24(const uint8_t *k, const uint8_t *in, const size_t inlen, } b = v1 ^ v3; - U32TO8_LE(out, b); + ISC_U32TO8_LE(out, b); } diff --git a/lib/isccc/cc.c b/lib/isccc/cc.c index 52914ed5ae..23eaf9d629 100644 --- a/lib/isccc/cc.c +++ b/lib/isccc/cc.c @@ -113,14 +113,14 @@ value_towire(isccc_sexpr_t *elt, isc_buffer_t **buffer) { if (isccc_sexpr_binaryp(elt)) { vr = isccc_sexpr_tobinary(elt); len = REGION_SIZE(*vr); - result = isc_buffer_reserve(buffer, 1 + 4); + result = isc_buffer_reserve(*buffer, 1 + 4); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } isc_buffer_putuint8(*buffer, ISCCC_CCMSGTYPE_BINARYDATA); isc_buffer_putuint32(*buffer, len); - result = isc_buffer_reserve(buffer, len); + result = isc_buffer_reserve(*buffer, len); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } @@ -129,7 +129,7 @@ value_towire(isccc_sexpr_t *elt, isc_buffer_t **buffer) { unsigned int used; isc_buffer_t b; - result = isc_buffer_reserve(buffer, 1 + 4); + result = isc_buffer_reserve(*buffer, 1 + 4); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } @@ -163,7 +163,7 @@ value_towire(isccc_sexpr_t *elt, isc_buffer_t **buffer) { unsigned int used; isc_buffer_t b; - result = isc_buffer_reserve(buffer, 1 + 4); + result = isc_buffer_reserve(*buffer, 1 + 4); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } @@ -217,7 +217,7 @@ table_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer) { /* * Emit the key name. */ - result = isc_buffer_reserve(buffer, 1 + len); + result = isc_buffer_reserve(*buffer, 1 + len); if (result != ISC_R_SUCCESS) { return (ISC_R_NOSPACE); } @@ -313,7 +313,7 @@ isccc_cc_towire(isccc_sexpr_t *alist, isc_buffer_t **buffer, uint32_t algorithm, unsigned int hmac_base, signed_base; isc_result_t result; - result = isc_buffer_reserve(buffer, + result = isc_buffer_reserve(*buffer, 4 + ((algorithm == ISCCC_ALG_HMACMD5) ? sizeof(auth_hmd5) : sizeof(auth_hsha))); diff --git a/lib/ns/client.c b/lib/ns/client.c index 39ef9acd9f..0bab7dbb51 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -1166,7 +1166,8 @@ compute_cookie(ns_client_t *client, uint32_t when, uint32_t nonce, cp = isc_buffer_used(buf); isc_buffer_putmem(buf, client->cookie, 8); isc_buffer_putuint8(buf, NS_COOKIE_VERSION_1); - isc_buffer_putuint24(buf, 0); /* Reserved */ + isc_buffer_putuint8(buf, 0); /* Reserved */ + isc_buffer_putuint16(buf, 0); /* Reserved */ isc_buffer_putuint32(buf, when); memmove(input, cp, 16); diff --git a/tests/isc/buffer_test.c b/tests/isc/buffer_test.c index 8335248fa0..09e1038e46 100644 --- a/tests/isc/buffer_test.c +++ b/tests/isc/buffer_test.c @@ -42,48 +42,44 @@ ISC_RUN_TEST_IMPL(isc_buffer_reserve) { UNUSED(state); b = NULL; - isc_buffer_allocate(mctx, &b, 1024); - assert_int_equal(b->length, 1024); + isc_buffer_allocate(mctx, &b, ISC_BUFFER_INCR); + assert_int_equal(b->length, ISC_BUFFER_INCR); /* - * 1024 bytes should already be available, so this call does + * 512 bytes should already be available, so this call does * nothing. */ - result = isc_buffer_reserve(&b, 1024); + result = isc_buffer_reserve(b, 512); assert_int_equal(result, ISC_R_SUCCESS); - assert_true(ISC_BUFFER_VALID(b)); assert_non_null(b); - assert_int_equal(b->length, 1024); + assert_int_equal(b->length, ISC_BUFFER_INCR); /* - * This call should grow it to 2048 bytes as only 1024 bytes are + * This call should grow it to 1536 bytes as only 1024 bytes are * available in the buffer. */ - result = isc_buffer_reserve(&b, 1025); + result = isc_buffer_reserve(b, 1025); assert_int_equal(result, ISC_R_SUCCESS); - assert_true(ISC_BUFFER_VALID(b)); assert_non_null(b); - assert_int_equal(b->length, 2048); + assert_int_equal(b->length, 3 * ISC_BUFFER_INCR); /* - * 2048 bytes should already be available, so this call does + * 1536 bytes should already be available, so this call does * nothing. */ - result = isc_buffer_reserve(&b, 2000); + result = isc_buffer_reserve(b, 1500); assert_int_equal(result, ISC_R_SUCCESS); - assert_true(ISC_BUFFER_VALID(b)); assert_non_null(b); - assert_int_equal(b->length, 2048); + assert_int_equal(b->length, 3 * ISC_BUFFER_INCR); /* - * This call should grow it to 4096 bytes as only 2048 bytes are + * This call should grow it to 4096 bytes as only 1536 bytes are * available in the buffer. */ - result = isc_buffer_reserve(&b, 3000); + result = isc_buffer_reserve(b, 3585); assert_int_equal(result, ISC_R_SUCCESS); - assert_true(ISC_BUFFER_VALID(b)); assert_non_null(b); - assert_int_equal(b->length, 4096); + assert_int_equal(b->length, 8 * ISC_BUFFER_INCR); /* Consume some of the buffer so we can run the next test. */ isc_buffer_add(b, 4096); @@ -91,11 +87,10 @@ ISC_RUN_TEST_IMPL(isc_buffer_reserve) { /* * This call should fail and leave buffer untouched. */ - result = isc_buffer_reserve(&b, UINT_MAX); + result = isc_buffer_reserve(b, UINT_MAX); assert_int_equal(result, ISC_R_NOMEMORY); - assert_true(ISC_BUFFER_VALID(b)); assert_non_null(b); - assert_int_equal(b->length, 4096); + assert_int_equal(b->length, 8 * ISC_BUFFER_INCR); isc_buffer_free(&b); } @@ -113,8 +108,6 @@ ISC_RUN_TEST_IMPL(isc_buffer_dynamic) { assert_non_null(b); assert_int_equal(b->length, last_length); - isc_buffer_setautorealloc(b, true); - isc_buffer_putuint8(b, 1); for (i = 0; i < 1000; i++) { @@ -136,14 +129,6 @@ ISC_RUN_TEST_IMPL(isc_buffer_dynamic) { assert_true(b->length - last_length >= 10000 * 2); - last_length += 10000 * 2; - for (i = 0; i < 10000; i++) { - isc_buffer_putuint24(b, 1); - } - assert_true(b->length - last_length >= 10000 * 3); - - last_length += 10000 * 3; - for (i = 0; i < 10000; i++) { isc_buffer_putuint32(b, 1); } @@ -174,16 +159,9 @@ ISC_RUN_TEST_IMPL(isc_buffer_copyregion) { assert_int_equal(result, ISC_R_SUCCESS); /* - * Appending more data to the buffer should fail. + * Appending should succeed. */ result = isc_buffer_copyregion(b, &r); - assert_int_equal(result, ISC_R_NOSPACE); - - /* - * Enable auto reallocation and retry. Appending should now succeed. - */ - isc_buffer_setautorealloc(b, true); - result = isc_buffer_copyregion(b, &r); assert_int_equal(result, ISC_R_SUCCESS); isc_buffer_free(&b); @@ -204,7 +182,6 @@ ISC_RUN_TEST_IMPL(isc_buffer_printf) { */ b = NULL; isc_buffer_allocate(mctx, &b, 0); - isc_buffer_setautorealloc(b, true); /* * Sanity check.