2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-31 14:35:26 +00:00

Add isc_buffer_setmctx() and isc_buffer_clearmctx() function

Add two extra functions needed by StreamDNS:

1. isc_buffer_setmctx() sets the buffer internal memory context, so we
   can use isc_buffer_reserve() on the buffer.  For this, we also need
   to track whether the .base was dynamically allocated or not.  This
   needs to be called after isc_buffer_init() and before first
   isc_buffer_reserve() call.

2. isc_buffer_clearmctx() clears the buffer internal memory context, and
   frees any dynamically allocated buffer.  This needs to be called
   after the last isc_buffer_reserve() call and before calling the
   isc_buffer_invalidate()
This commit is contained in:
Ondřej Surý
2022-12-16 11:43:20 +01:00
parent 8e3a86f6dd
commit e6062ee3ae

View File

@@ -179,17 +179,16 @@ struct isc_buffer {
unsigned int used;
unsigned int current;
unsigned int active;
/*! The extra bytes allocated for dynamic buffer */
unsigned int extra;
/*@}*/
/*! 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;
};
#define ISC_BUFFER_STATIC_SIZE 512
/***
*** Functions
***/
@@ -210,6 +209,15 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
*\li Changing the buffer's length field is not permitted.
*/
static inline void
isc_buffer_setmctx(isc_buffer_t *b, isc_mem_t *mctx);
static inline void
isc_buffer_clearmctx(isc_buffer_t *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 *dynbuffer, unsigned int size);
/*!<
@@ -1073,17 +1081,35 @@ isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dbufp,
isc_buffer_init(dbuf, bdata, length);
dbuf->extra = length;
dbuf->mctx = mctx;
isc_buffer_setmctx(dbuf, mctx);
*dbufp = dbuf;
}
static inline void
isc_buffer_setmctx(isc_buffer_t *b, isc_mem_t *mctx) {
REQUIRE(ISC_BUFFER_VALID(b));
b->mctx = mctx;
}
static inline void
isc_buffer_clearmctx(isc_buffer_t *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 *dbuf, unsigned int size) {
REQUIRE(ISC_BUFFER_VALID(dbuf));
size_t len;
uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
size_t len;
len = dbuf->length;
if ((len - dbuf->used) >= size) {
@@ -1107,9 +1133,11 @@ isc_buffer_reserve(isc_buffer_t *dbuf, unsigned int size) {
return (ISC_R_NOMEMORY);
}
if (dbuf->base == bdata) {
if (!dbuf->dynamic) {
void *old_base = dbuf->base;
dbuf->base = isc_mem_get(dbuf->mctx, len);
memmove(dbuf->base, bdata, dbuf->used);
memmove(dbuf->base, old_base, dbuf->used);
dbuf->dynamic = true;
} else {
dbuf->base = isc_mem_reget(dbuf->mctx, dbuf->base, dbuf->length,
len);
@@ -1126,15 +1154,11 @@ isc_buffer_free(isc_buffer_t **dbufp) {
isc_buffer_t *dbuf = *dbufp;
isc_mem_t *mctx = dbuf->mctx;
uint8_t *bdata = (uint8_t *)dbuf + sizeof(*dbuf);
unsigned int extra = dbuf->extra;
*dbufp = NULL; /* destroy external reference */
dbuf->mctx = NULL;
if (dbuf->base != bdata) {
isc_mem_put(mctx, dbuf->base, dbuf->length);
}
isc_buffer_clearmctx(dbuf);
isc_buffer_invalidate(dbuf);
isc_mem_put(mctx, dbuf, sizeof(*dbuf) + extra);