mirror of
https://github.com/isc-projects/bind9.git
synced 2026-06-03 13:59:27 -04:00
When parsing a message, add an offsets table to each name. Also allow callers
rendering a message to get temporary offsets tables to attach to names added to the message.
This commit is contained in:
parent
31efcf6478
commit
55f3daa4ea
2 changed files with 102 additions and 13 deletions
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: message.h,v 1.90 2001/02/02 22:05:04 gson Exp $ */
|
||||
/* $Id: message.h,v 1.91 2001/02/13 01:02:59 bwelling Exp $ */
|
||||
|
||||
#ifndef DNS_MESSAGE_H
|
||||
#define DNS_MESSAGE_H 1
|
||||
|
|
@ -59,11 +59,12 @@
|
|||
*
|
||||
* The same applies to rdatasets.
|
||||
*
|
||||
* On the other hand, rdatalists and rdatas allocated using
|
||||
* On the other hand, offsets, rdatalists and rdatas allocated using
|
||||
* dns_message_gettemp*() will always be freed automatically
|
||||
* when the message is reset or destroyed; calling dns_message_puttemp*()
|
||||
* on these is optional and serves only to enable the item to be reused
|
||||
* multiple times during the lifetime of the message.
|
||||
* on rdatalists and rdatas is optional and serves only to enable the item
|
||||
* to be reused multiple times during the lifetime of the message; offsets
|
||||
* cannot be reused.
|
||||
*
|
||||
* Buffers allocated using isc_buffer_allocate() can be automatically freed
|
||||
* as well by giving the buffer to the message using dns_message_takebuffer().
|
||||
|
|
@ -206,6 +207,7 @@ struct dns_message {
|
|||
|
||||
ISC_LIST(dns_msgblock_t) rdatas;
|
||||
ISC_LIST(dns_msgblock_t) rdatalists;
|
||||
ISC_LIST(dns_msgblock_t) offsets;
|
||||
|
||||
ISC_LIST(dns_rdata_t) freerdata;
|
||||
ISC_LIST(dns_rdatalist_t) freerdatalist;
|
||||
|
|
@ -745,6 +747,23 @@ dns_message_gettempname(dns_message_t *msg, dns_name_t **item);
|
|||
* ISC_R_NOMEMORY -- No item can be allocated.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item);
|
||||
/*
|
||||
* Return an offsets array that can be used for any temporary purpose,
|
||||
* such as attaching to a temporary name. The offsets will be freed
|
||||
* when the message is destroyed or reset.
|
||||
*
|
||||
* Requires:
|
||||
* msg be a valid message
|
||||
*
|
||||
* item != NULL && *item == NULL
|
||||
*
|
||||
* Returns:
|
||||
* ISC_R_SUCCESS -- All is well.
|
||||
* ISC_R_NOMEMORY -- No item can be allocated.
|
||||
*/
|
||||
|
||||
isc_result_t
|
||||
dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item);
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* $Id: message.c,v 1.174 2001/01/27 02:28:33 bwelling Exp $ */
|
||||
/* $Id: message.c,v 1.175 2001/02/13 01:02:57 bwelling Exp $ */
|
||||
|
||||
/***
|
||||
*** Imports
|
||||
|
|
@ -70,6 +70,7 @@
|
|||
*/
|
||||
#define SCRATCHPAD_SIZE 512
|
||||
#define NAME_COUNT 8
|
||||
#define OFFSET_COUNT NAME_COUNT
|
||||
#define RDATA_COUNT 8
|
||||
#define RDATALIST_COUNT 8
|
||||
#define RDATASET_COUNT RDATALIST_COUNT
|
||||
|
|
@ -316,6 +317,28 @@ newrdatalist(dns_message_t *msg) {
|
|||
return (rdatalist);
|
||||
}
|
||||
|
||||
static inline dns_offsets_t *
|
||||
newoffsets(dns_message_t *msg) {
|
||||
dns_msgblock_t *msgblock;
|
||||
dns_offsets_t *offsets;
|
||||
|
||||
msgblock = ISC_LIST_TAIL(msg->offsets);
|
||||
offsets = msgblock_get(msgblock, dns_offsets_t);
|
||||
if (offsets == NULL) {
|
||||
msgblock = msgblock_allocate(msg->mctx,
|
||||
sizeof(dns_offsets_t),
|
||||
OFFSET_COUNT);
|
||||
if (msgblock == NULL)
|
||||
return (NULL);
|
||||
|
||||
ISC_LIST_APPEND(msg->offsets, msgblock, link);
|
||||
|
||||
offsets = msgblock_get(msgblock, dns_offsets_t);
|
||||
}
|
||||
|
||||
return (offsets);
|
||||
}
|
||||
|
||||
static inline void
|
||||
msginitheader(dns_message_t *m) {
|
||||
m->id = 0;
|
||||
|
|
@ -552,6 +575,19 @@ msgreset(dns_message_t *msg, isc_boolean_t everything) {
|
|||
msgblock = next_msgblock;
|
||||
}
|
||||
|
||||
msgblock = ISC_LIST_HEAD(msg->offsets);
|
||||
INSIST(msgblock != NULL);
|
||||
if (!everything) {
|
||||
msgblock_reset(msgblock);
|
||||
msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
}
|
||||
while (msgblock != NULL) {
|
||||
next_msgblock = ISC_LIST_NEXT(msgblock, link);
|
||||
ISC_LIST_UNLINK(msg->offsets, msgblock, link);
|
||||
msgblock_free(msg->mctx, msgblock, sizeof(dns_offsets_t));
|
||||
msgblock = next_msgblock;
|
||||
}
|
||||
|
||||
if (msg->need_cctx_cleanup == 1)
|
||||
dns_compress_invalidate(&msg->cctx);
|
||||
|
||||
|
|
@ -671,6 +707,7 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
|
|||
m->rdspool = NULL;
|
||||
ISC_LIST_INIT(m->rdatas);
|
||||
ISC_LIST_INIT(m->rdatalists);
|
||||
ISC_LIST_INIT(m->offsets);
|
||||
ISC_LIST_INIT(m->freerdata);
|
||||
ISC_LIST_INIT(m->freerdatalist);
|
||||
|
||||
|
|
@ -713,6 +750,12 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
|
|||
ISC_LIST_APPEND(m->rdatalists, msgblock, link);
|
||||
}
|
||||
|
||||
msgblock = msgblock_allocate(mctx, sizeof(dns_offsets_t),
|
||||
OFFSET_COUNT);
|
||||
if (msgblock == NULL)
|
||||
goto cleanup;
|
||||
ISC_LIST_APPEND(m->offsets, msgblock, link);
|
||||
|
||||
*msgp = m;
|
||||
return (ISC_R_SUCCESS);
|
||||
|
||||
|
|
@ -723,6 +766,9 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
|
|||
msgblock = ISC_LIST_HEAD(m->rdatas);
|
||||
if (msgblock != NULL)
|
||||
msgblock_free(mctx, msgblock, sizeof(dns_rdata_t));
|
||||
msgblock = ISC_LIST_HEAD(m->rdatalists);
|
||||
if (msgblock != NULL)
|
||||
msgblock_free(mctx, msgblock, sizeof(dns_rdatalist_t));
|
||||
dynbuf = ISC_LIST_HEAD(m->scratchpad);
|
||||
if (dynbuf != NULL) {
|
||||
ISC_LIST_UNLINK(m->scratchpad, dynbuf, link);
|
||||
|
|
@ -826,7 +872,6 @@ getname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
|
|||
*/
|
||||
tries = 0;
|
||||
while (tries < 2) {
|
||||
dns_name_init(name, NULL);
|
||||
result = dns_name_fromwire(name, source, dctx, ISC_FALSE,
|
||||
scratch);
|
||||
|
||||
|
|
@ -838,6 +883,7 @@ getname(dns_name_t *name, isc_buffer_t *source, dns_message_t *msg,
|
|||
return (result);
|
||||
|
||||
scratch = currentbuffer(msg);
|
||||
dns_name_reset(name);
|
||||
} else {
|
||||
return (result);
|
||||
}
|
||||
|
|
@ -918,6 +964,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
unsigned int count;
|
||||
dns_name_t *name;
|
||||
dns_name_t *name2;
|
||||
dns_offsets_t *offsets;
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_rdatalist_t *rdatalist;
|
||||
isc_result_t result;
|
||||
|
|
@ -942,6 +989,11 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
if (name == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
free_name = ISC_TRUE;
|
||||
|
||||
offsets = newoffsets(msg);
|
||||
if (offsets == NULL)
|
||||
goto cleanup;
|
||||
dns_name_init(name, *offsets);
|
||||
|
||||
/*
|
||||
* Parse the name out of this packet.
|
||||
|
|
@ -1083,6 +1135,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
unsigned int count, rdatalen;
|
||||
dns_name_t *name;
|
||||
dns_name_t *name2;
|
||||
dns_offsets_t *offsets;
|
||||
dns_rdataset_t *rdataset;
|
||||
dns_rdatalist_t *rdatalist;
|
||||
isc_result_t result;
|
||||
|
|
@ -1114,6 +1167,11 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
|
|||
return (ISC_R_NOMEMORY);
|
||||
free_name = ISC_TRUE;
|
||||
|
||||
offsets = newoffsets(msg);
|
||||
if (offsets == NULL)
|
||||
goto cleanup;
|
||||
dns_name_init(name, *offsets);
|
||||
|
||||
/*
|
||||
* Parse the name out of this packet.
|
||||
*/
|
||||
|
|
@ -2126,15 +2184,16 @@ dns_message_gettempname(dns_message_t *msg, dns_name_t **item) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
|
||||
isc_result_t
|
||||
dns_message_gettempoffsets(dns_message_t *msg, dns_offsets_t **item) {
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(item != NULL && *item != NULL);
|
||||
REQUIRE(item != NULL && *item == NULL);
|
||||
|
||||
if (dns_name_dynamic(*item))
|
||||
dns_name_free(*item, msg->mctx);
|
||||
isc_mempool_put(msg->namepool, *item);
|
||||
*item = NULL;
|
||||
*item = newoffsets(msg);
|
||||
if (*item == NULL)
|
||||
return (ISC_R_NOMEMORY);
|
||||
|
||||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
isc_result_t
|
||||
|
|
@ -2175,6 +2234,17 @@ dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item) {
|
|||
return (ISC_R_SUCCESS);
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_puttempname(dns_message_t *msg, dns_name_t **item) {
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
REQUIRE(item != NULL && *item != NULL);
|
||||
|
||||
if (dns_name_dynamic(*item))
|
||||
dns_name_free(*item, msg->mctx);
|
||||
isc_mempool_put(msg->namepool, *item);
|
||||
*item = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item) {
|
||||
REQUIRE(DNS_MESSAGE_VALID(msg));
|
||||
|
|
|
|||
Loading…
Reference in a new issue