Beispiel #1
0
isc_result_t
isc_buffer_reallocate(isc_buffer_t **dynbuffer, unsigned int length) {
	unsigned char *bdata;

	REQUIRE(dynbuffer != NULL);
	REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
	REQUIRE((*dynbuffer)->mctx != NULL);

	if ((*dynbuffer)->length > length)
		return (ISC_R_NOSPACE);

	/*
	 * XXXMUKS: This is far more expensive than plain realloc() as
	 * it doesn't remap pages, but does ordinary copy. So is
	 * isc_mem_reallocate(), which has additional issues.
	 */
	bdata = isc_mem_get((*dynbuffer)->mctx, length);
	if (bdata == NULL)
		return (ISC_R_NOMEMORY);

	memmove(bdata, (*dynbuffer)->base, (*dynbuffer)->length);
	isc_mem_put((*dynbuffer)->mctx, (*dynbuffer)->base,
		    (*dynbuffer)->length);

	(*dynbuffer)->base = bdata;
	(*dynbuffer)->length = length;

	return (ISC_R_SUCCESS);
}
Beispiel #2
0
isc_result_t
isc_buffer_reserve(isc_buffer_t **dynbuffer, unsigned int size) {
	isc_uint64_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);

	return (isc_buffer_reallocate(dynbuffer, (unsigned int) len));
}
Beispiel #3
0
isc_result_t
isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) {
	unsigned char *base;
	unsigned int available;
	isc_result_t result;

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(r != NULL);

	/*
	 * XXXDCL
	 */
	base = isc_buffer_used(b);
	available = isc_buffer_availablelength(b);
	if (ISC_UNLIKELY(b->autore)) {
		result = isc_buffer_reserve(&b, r->length);
		if (result != ISC_R_SUCCESS)
			return (result);
	}
	if (r->length > available)
		return (ISC_R_NOSPACE);
	memmove(base, r->base, r->length);
	b->used += r->length;

	return (ISC_R_SUCCESS);
}
Beispiel #4
0
isc_result_t
isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
		    unsigned int length)
{
	isc_buffer_t *dbuf;
	unsigned char * bdata;
	REQUIRE(dynbuffer != NULL);
	REQUIRE(*dynbuffer == NULL);

	dbuf = isc_mem_get(mctx, sizeof(isc_buffer_t));
	if (dbuf == NULL)
		return (ISC_R_NOMEMORY);

	bdata = isc_mem_get(mctx, length);
	if (bdata == NULL) {
		isc_mem_put(mctx, dbuf, sizeof(isc_buffer_t));
		return (ISC_R_NOMEMORY);
	}

	isc_buffer_init(dbuf, bdata, length);
	dbuf->mctx = mctx;

	ENSURE(ISC_BUFFER_VALID(dbuf));

	*dynbuffer = dbuf;

	return (ISC_R_SUCCESS);
}
Beispiel #5
0
void
isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(b->used + 4 <= b->length);

	ISC__BUFFER_PUTUINT32(b, val);
}
Beispiel #6
0
/**
 * @pre closure points to a valid isc_buffer
 * @pre isc_buffer has non-NULL mctx
 * @pre isc_buffer has NULL buffer OR a buffer allocated from mctx
 *
 * @post closure contains \0 terminated string which is concatenation
 *       of previous context and input text
 */
static void
buffer_append_str(void *closure, const char *text, int textlen) {
	isc_buffer_t *out_buf = closure;
	isc_region_t new_space;
	isc_region_t old_space;

	REQUIRE(ISC_BUFFER_VALID(out_buf));
	REQUIRE(out_buf->mctx != NULL);
	REQUIRE(text != NULL);

	/* Allocate sufficiently long output buffer. */
	isc_buffer_region(out_buf, &old_space);
	new_space.length = isc_buffer_length(out_buf) + textlen + 1;
	new_space.base = isc_mem_get(out_buf->mctx, new_space.length);
	RUNTIME_CHECK(new_space.base != NULL);
	isc_buffer_reinit(out_buf, new_space.base, new_space.length);
	if (old_space.base != NULL)
		isc_mem_put(out_buf->mctx, old_space.base, old_space.length);

	/* Append output text and \0-terminate it.
	 * Overwrite \0 at the end if needed. */
	if (isc_buffer_usedlength(out_buf) != 0)
		/* Previous string is \0 terminated, chop \0. */
		isc_buffer_subtract(out_buf, 1);
	isc_buffer_putstr(out_buf, text);
	isc_buffer_putuint8(out_buf, '\0');
}
Beispiel #7
0
void
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
		   unsigned int length)
{
	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(b->used + length <= b->length);

	ISC__BUFFER_PUTMEM(b, base, length);
}
Beispiel #8
0
void
isc__buffer_first(isc_buffer_t *b) {
	/*
	 * Make the consumed region empty.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));

	ISC__BUFFER_FIRST(b);
}
Beispiel #9
0
void
isc__buffer_clear(isc_buffer_t *b) {
	/*
	 * Make the used region empty.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));

	ISC__BUFFER_CLEAR(b);
}
Beispiel #10
0
void
isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) {
	/*
	 * Make 'r' refer to the used region of 'b'.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(r != NULL);

	ISC__BUFFER_USEDREGION(b, r);
}
Beispiel #11
0
void
isc__buffer_subtract(isc_buffer_t *b, unsigned int n) {
	/*
	 * Decrease the 'used' region of 'b' by 'n' bytes.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(b->used >= n);

	ISC__BUFFER_SUBTRACT(b, n);
}
Beispiel #12
0
void
isc__buffer_add(isc_buffer_t *b, unsigned int n) {
	/*
	 * Increase the 'used' region of 'b' by 'n' bytes.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(b->used + n <= b->length);

	ISC__BUFFER_ADD(b, n);
}
Beispiel #13
0
void
isc__buffer_back(isc_buffer_t *b, unsigned int n) {
	/*
	 * Decrease the 'consumed' region of 'b' by 'n' bytes.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(n <= b->current);

	ISC__BUFFER_BACK(b, n);
}
Beispiel #14
0
void
isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) {
	/*
	 * Make 'r' refer to the remaining region of 'b'.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(r != NULL);

	ISC__BUFFER_REMAININGREGION(b, r);
}
Beispiel #15
0
void
isc__buffer_forward(isc_buffer_t *b, unsigned int n) {
	/*
	 * Increase the 'consumed' region of 'b' by 'n' bytes.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(b->current + n <= b->used);

	ISC__BUFFER_FORWARD(b, n);
}
Beispiel #16
0
void
isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) {
	/*
	 * Make 'r' refer to the available region of 'b'.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(r != NULL);

	ISC__BUFFER_AVAILABLEREGION(b, r);
}
Beispiel #17
0
void
isc__buffer_setactive(isc_buffer_t *b, unsigned int n) {
	/*
	 * Sets the end of the active region 'n' bytes after current.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(b->current + n <= b->used);

	ISC__BUFFER_SETACTIVE(b, n);
}
Beispiel #18
0
void
isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) {
	/*
	 * Make 'r' refer to the active region of 'b'.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(r != NULL);

	ISC__BUFFER_ACTIVEREGION(b, r);
}
Beispiel #19
0
void
isc__buffer_invalidate(isc_buffer_t *b) {
	/*
	 * Make 'b' an invalid buffer.
	 */

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(!ISC_LINK_LINKED(b, link));
	REQUIRE(b->mctx == NULL);

	ISC__BUFFER_INVALIDATE(b);
}
Beispiel #20
0
void
isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
	isc_result_t result;
	REQUIRE(ISC_BUFFER_VALID(b));
	if (ISC_UNLIKELY(b->autore)) {
		result = isc_buffer_reserve(&b, 4);
		REQUIRE(result == ISC_R_SUCCESS);
	}
	REQUIRE(isc_buffer_availablelength(b) >= 4);

	ISC__BUFFER_PUTUINT32(b, val);
}
Beispiel #21
0
void
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
	isc_uint16_t valhi;
	isc_uint32_t vallo;

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(b->used + 6 <= b->length);

	valhi = (isc_uint16_t)(val >> 32);
	vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
	ISC__BUFFER_PUTUINT16(b, valhi);
	ISC__BUFFER_PUTUINT32(b, vallo);
}
Beispiel #22
0
void
isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
		   unsigned int length)
{
	isc_result_t result;
	REQUIRE(ISC_BUFFER_VALID(b));
	if (ISC_UNLIKELY(b->autore)) {
		result = isc_buffer_reserve(&b, length);
		REQUIRE(result == ISC_R_SUCCESS);
	}
	REQUIRE(isc_buffer_availablelength(b) >= length);

	ISC__BUFFER_PUTMEM(b, base, length);
}
Beispiel #23
0
unsigned int
isc_bufferlist_availablecount(isc_bufferlist_t *bl) {
	isc_buffer_t *buffer;
	unsigned int length;

	REQUIRE(bl != NULL);

	length = 0;
	buffer = ISC_LIST_HEAD(*bl);
	while (buffer != NULL) {
		REQUIRE(ISC_BUFFER_VALID(buffer));
		length += isc_buffer_availablelength(buffer);
		buffer = ISC_LIST_NEXT(buffer, link);
	}

	return (length);
}
Beispiel #24
0
void
isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
	isc_result_t result;
	isc_uint16_t valhi;
	isc_uint32_t vallo;

	REQUIRE(ISC_BUFFER_VALID(b));
	if (ISC_UNLIKELY(b->autore)) {
		result = isc_buffer_reserve(&b, 6);
		REQUIRE(result == ISC_R_SUCCESS);
	}
	REQUIRE(isc_buffer_availablelength(b) >= 6);

	valhi = (isc_uint16_t)(val >> 32);
	vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
	ISC__BUFFER_PUTUINT16(b, valhi);
	ISC__BUFFER_PUTUINT32(b, vallo);
}
Beispiel #25
0
isc_uint8_t
isc_buffer_getuint8(isc_buffer_t *b) {
	unsigned char *cp;
	isc_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 = ((isc_uint8_t)(cp[0]));

	return (result);
}
Beispiel #26
0
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));
}
Beispiel #27
0
void
isc__buffer_putstr(isc_buffer_t *b, const char *source) {
	unsigned int l;
	unsigned char *cp;

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(source != NULL);

	/*
	 * Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once.
	 */
	l = strlen(source);

	REQUIRE(l <= isc_buffer_availablelength(b));

	cp = isc_buffer_used(b);
	memcpy(cp, source, l);
	b->used += l;
}
Beispiel #28
0
isc_result_t
isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) {
	unsigned char *base;
	unsigned int available;

	REQUIRE(ISC_BUFFER_VALID(b));
	REQUIRE(r != NULL);

	/*
	 * XXXDCL
	 */
	base = isc_buffer_used(b);
	available = isc_buffer_availablelength(b);
	if (r->length > available)
		return (ISC_R_NOSPACE);
	memcpy(base, r->base, r->length);
	b->used += r->length;

	return (ISC_R_SUCCESS);
}
Beispiel #29
0
isc_uint16_t
isc_buffer_getuint16(isc_buffer_t *b) {
	unsigned char *cp;
	isc_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);
}
Beispiel #30
0
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, &region);

	result = isc_buffer_allocate(mctx, &dst, region.length);
	if (result != ISC_R_SUCCESS)
		return (result);

	result = isc_buffer_copyregion(dst, &region);
	RUNTIME_CHECK(result == ISC_R_SUCCESS); /* NOSPACE is impossible */
	*dstp = dst;
	return (ISC_R_SUCCESS);
}