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

Changes to message.c/h to use memory pools for names. Coming soon:

same thing for rdata, rdatalist, and rdatasets.

Also implement dns_message_takebuffer().

See comments in message.h for news.
This commit is contained in:
Michael Graff
1999-09-10 02:48:32 +00:00
parent c3a4d8072c
commit af6e7e5cd2
2 changed files with 164 additions and 112 deletions

View File

@@ -187,40 +187,6 @@ currentbuffer(dns_message_t *msg)
return (dynbuf);
}
static inline void
releasename(dns_message_t *msg, dns_name_t *name)
{
ISC_LIST_PREPEND(msg->freename, name, link);
}
static inline dns_name_t *
newname(dns_message_t *msg)
{
dns_msgblock_t *msgblock;
dns_name_t *name;
name = ISC_LIST_HEAD(msg->freename);
if (name != NULL) {
ISC_LIST_UNLINK(msg->freename, name, link);
return (name);
}
msgblock = ISC_LIST_TAIL(msg->names);
name = msgblock_get(msgblock, dns_name_t);
if (name == NULL) {
msgblock = msgblock_allocate(msg->mctx, sizeof(dns_name_t),
NAME_COUNT);
if (msgblock == NULL)
return (NULL);
ISC_LIST_APPEND(msg->names, msgblock, link);
name = msgblock_get(msgblock, dns_name_t);
}
return (name);
}
static inline void
releaserdata(dns_message_t *msg, dns_rdata_t *rdata)
{
@@ -396,6 +362,7 @@ msgresetnames(dns_message_t *msg, unsigned int first_section) {
dns_rdataset_disassociate(rds);
rds = next_rds;
}
isc_mempool_put(msg->namepool, name);
name = next_name;
}
}
@@ -411,7 +378,6 @@ msgreset(dns_message_t *msg, isc_boolean_t everything)
dns_msgblock_t *msgblock, *next_msgblock;
isc_buffer_t *dynbuf, *next_dynbuf;
dns_rdataset_t *rds;
dns_name_t *name;
dns_rdata_t *rdata;
dns_rdatalist_t *rdatalist;
@@ -430,11 +396,6 @@ msgreset(dns_message_t *msg, isc_boolean_t everything)
* The memory isn't lost since these are part of message blocks we
* have allocated.
*/
name = ISC_LIST_HEAD(msg->freename);
while (name != NULL) {
ISC_LIST_UNLINK(msg->freename, name, link);
name = ISC_LIST_HEAD(msg->freename);
}
rdata = ISC_LIST_HEAD(msg->freerdata);
while (rdata != NULL) {
ISC_LIST_UNLINK(msg->freerdata, rdata, link);
@@ -464,19 +425,6 @@ msgreset(dns_message_t *msg, isc_boolean_t everything)
dynbuf = next_dynbuf;
}
msgblock = ISC_LIST_HEAD(msg->names);
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->names, msgblock, link);
msgblock_free(msg->mctx, msgblock, sizeof(dns_name_t));
msgblock = next_msgblock;
}
msgblock = ISC_LIST_HEAD(msg->rdatas);
INSIST(msgblock != NULL);
if (!everything) {
@@ -537,6 +485,17 @@ msgreset(dns_message_t *msg, isc_boolean_t everything)
if (msg->tsigkey != NULL && dns_tsig_emptykey(msg->tsigkey))
dns_tsig_key_free(&msg->tsigkey);
/*
* cleanup the buffer cleanup list
*/
dynbuf = ISC_LIST_HEAD(msg->cleanup);
while (dynbuf != NULL) {
next_dynbuf = ISC_LIST_NEXT(dynbuf, link);
ISC_LIST_UNLINK(msg->scratchpad, dynbuf, link);
isc_buffer_free(&dynbuf);
dynbuf = next_dynbuf;
}
/*
* Set other bits to normal default values.
*/
@@ -548,7 +507,7 @@ dns_result_t
dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
{
dns_message_t *m;
isc_result_t iresult;
isc_result_t result;
dns_msgblock_t *msgblock;
isc_buffer_t *dynbuf;
unsigned int i;
@@ -563,52 +522,63 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
if (m == NULL)
return(DNS_R_NOMEMORY);
/*
* No allocations until further notice. Just initialize all lists
* and other members that are freed in the cleanup phase here.
*/
m->magic = DNS_MESSAGE_MAGIC;
m->from_to_wire = intent;
msginit(m);
for (i = 0 ; i < DNS_SECTION_MAX ; i++)
ISC_LIST_INIT(m->sections[i]);
m->mctx = mctx;
ISC_LIST_INIT(m->scratchpad);
ISC_LIST_INIT(m->names);
ISC_LIST_INIT(m->cleanup);
m->namepool = NULL;
ISC_LIST_INIT(m->rdatas);
ISC_LIST_INIT(m->rdatasets);
ISC_LIST_INIT(m->rdatalists);
ISC_LIST_INIT(m->freename);
ISC_LIST_INIT(m->freerdata);
ISC_LIST_INIT(m->freerdataset);
ISC_LIST_INIT(m->freerdatalist);
dynbuf = NULL;
iresult = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE,
ISC_BUFFERTYPE_BINARY);
if (iresult != ISC_R_SUCCESS)
goto cleanup1;
ISC_LIST_APPEND(m->scratchpad, dynbuf, link);
/*
* Ok, it is safe to allocate (and then "goto cleanup" if failure)
*/
msgblock = msgblock_allocate(mctx, sizeof(dns_name_t),
NAME_COUNT);
if (msgblock == NULL)
goto cleanup2;
ISC_LIST_APPEND(m->names, msgblock, link);
result = isc_mempool_create(m->mctx, sizeof(dns_name_t), &m->namepool);
if (result != ISC_R_SUCCESS)
goto cleanup;
isc_mempool_setfreemax(m->namepool, NAME_COUNT);
isc_mempool_setfillcount(m->namepool, NAME_COUNT);
dynbuf = NULL;
result = isc_buffer_allocate(mctx, &dynbuf, SCRATCHPAD_SIZE,
ISC_BUFFERTYPE_BINARY);
if (result != ISC_R_SUCCESS)
goto cleanup;
ISC_LIST_APPEND(m->scratchpad, dynbuf, link);
msgblock = msgblock_allocate(mctx, sizeof(dns_rdata_t),
RDATA_COUNT);
if (msgblock == NULL)
goto cleanup3;
goto cleanup;
ISC_LIST_APPEND(m->rdatas, msgblock, link);
msgblock = msgblock_allocate(mctx, sizeof(dns_rdataset_t),
RDATASET_COUNT);
if (msgblock == NULL)
goto cleanup4;
goto cleanup;
ISC_LIST_APPEND(m->rdatasets, msgblock, link);
if (intent == DNS_MESSAGE_INTENTPARSE) {
msgblock = msgblock_allocate(mctx, sizeof(dns_rdatalist_t),
RDATALIST_COUNT);
if (msgblock == NULL)
goto cleanup5;
goto cleanup;
ISC_LIST_APPEND(m->rdatalists, msgblock, link);
}
@@ -618,19 +588,18 @@ dns_message_create(isc_mem_t *mctx, unsigned int intent, dns_message_t **msgp)
/*
* Cleanup for error returns.
*/
cleanup5:
cleanup:
msgblock = ISC_LIST_HEAD(m->rdatasets);
msgblock_free(mctx, msgblock, sizeof(dns_rdataset_t));
cleanup4:
if (msgblock != NULL)
msgblock_free(mctx, msgblock, sizeof(dns_rdataset_t));
msgblock = ISC_LIST_HEAD(m->rdatas);
msgblock_free(mctx, msgblock, sizeof(dns_rdata_t));
cleanup3:
msgblock = ISC_LIST_HEAD(m->names);
msgblock_free(mctx, msgblock, sizeof(dns_name_t));
cleanup2:
if (msgblock != NULL)
msgblock_free(mctx, msgblock, sizeof(dns_rdata_t));
dynbuf = ISC_LIST_HEAD(m->scratchpad);
isc_buffer_free(&dynbuf);
cleanup1:
if (dynbuf != NULL)
isc_buffer_free(&dynbuf);
if (m->namepool != NULL)
isc_mempool_destroy(&m->namepool);
m->magic = 0;
isc_mem_put(mctx, m, sizeof(dns_message_t));
@@ -660,6 +629,7 @@ dns_message_destroy(dns_message_t **msgp)
*msgp = NULL;
msgreset(msg, ISC_TRUE);
isc_mempool_destroy(&msg->namepool);
msg->magic = 0;
isc_mem_put(msg->mctx, msg, sizeof(dns_message_t));
}
@@ -830,7 +800,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
section = &msg->sections[DNS_SECTION_QUESTION];
for (count = 0 ; count < msg->counts[DNS_SECTION_QUESTION] ; count++) {
name = newname(msg);
name = isc_mempool_get(msg->namepool);
if (name == NULL)
return (DNS_R_NOMEMORY);
@@ -841,7 +811,7 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
isc_buffer_setactive(source, r.length);
result = getname(name, source, msg, dctx);
if (result != DNS_R_SUCCESS)
return (result);
goto free_name;
/*
* Run through the section, looking to see if this name
@@ -865,18 +835,23 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
if (ISC_LIST_EMPTY(*section)) {
ISC_LIST_APPEND(*section, name, link);
} else {
return (DNS_R_FORMERR);
result = DNS_R_FORMERR;
goto free_name;
}
} else {
isc_mempool_put(msg->namepool, name);
name = name2;
name2 = NULL;
}
/*
* Get type and class.
*/
isc_buffer_remaining(source, &r);
if (r.length < 4)
return (DNS_R_UNEXPECTEDEND);
if (r.length < 4) {
result = DNS_R_UNEXPECTEDEND;
goto free_name;
}
rdtype = isc_buffer_getuint16(source);
rdclass = isc_buffer_getuint16(source);
@@ -888,25 +863,33 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
msg->state = DNS_SECTION_QUESTION;
msg->rdclass = rdclass;
msg->state = DNS_SECTION_QUESTION;
} else if (msg->rdclass != rdclass)
return (DNS_R_FORMERR);
} else if (msg->rdclass != rdclass) {
result = DNS_R_FORMERR;
goto free_name;
}
/*
* Can't ask the same question twice.
*/
result = dns_message_findtype(name, rdtype, 0, NULL);
if (result == DNS_R_SUCCESS)
return (DNS_R_FORMERR);
if (result == DNS_R_SUCCESS) {
result = DNS_R_FORMERR;
goto free_name;
}
/*
* Allocate a new rdatalist.
*/
rdatalist = newrdatalist(msg);
if (rdatalist == NULL)
return (DNS_R_NOMEMORY);
if (rdatalist == NULL) {
result = DNS_R_NOMEMORY;
goto free_name;
}
rdataset = newrdataset(msg);
if (rdataset == NULL)
return (DNS_R_NOMEMORY);
if (rdataset == NULL) {
result = DNS_R_NOMEMORY;
goto free_rdatalist;
}
/*
* Convert rdatalist to rdataset, and attach the latter to
@@ -920,13 +903,21 @@ getquestions(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx)
dns_rdataset_init(rdataset);
result = dns_rdatalist_tordataset(rdatalist, rdataset);
if (result != DNS_R_SUCCESS)
return (result);
goto free_rdataset;
rdataset->attributes |= DNS_RDATASETATTR_QUESTION;
ISC_LIST_APPEND(name->list, rdataset, link);
}
return (DNS_R_SUCCESS);
free_rdataset:
free_rdatalist:
free_name:
isc_mempool_put(msg->namepool, name);
return (result);
}
static dns_result_t
@@ -953,7 +944,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
section = &msg->sections[sectionid];
skip_search = ISC_FALSE;
name = newname(msg);
name = isc_mempool_get(msg->namepool);
if (name == NULL)
return (DNS_R_NOMEMORY);
@@ -1057,7 +1048,7 @@ getsection(isc_buffer_t *source, dns_message_t *msg, dns_decompress_t *dctx,
* If it is a new name, append to the section.
*/
if (result == DNS_R_SUCCESS) {
releasename(msg, name);
isc_mempool_put(msg->namepool, name);
name = name2;
} else {
ISC_LIST_APPEND(*section, name, link);
@@ -1652,13 +1643,23 @@ dns_message_gettempname(dns_message_t *msg, dns_name_t **item)
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(item != NULL && *item == NULL);
*item = newname(msg);
*item = isc_mempool_get(msg->namepool);
if (*item == NULL)
return (DNS_R_NOMEMORY);
return (DNS_R_SUCCESS);
}
void
dns_message_puttempname(dns_message_t *msg, dns_name_t **item)
{
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(item != NULL && *item != NULL);
isc_mempool_put(msg->namepool, *item);
*item = NULL;
}
dns_result_t
dns_message_gettemprdata(dns_message_t *msg, dns_rdata_t **item)
{
@@ -1698,16 +1699,6 @@ dns_message_gettemprdatalist(dns_message_t *msg, dns_rdatalist_t **item)
return (DNS_R_SUCCESS);
}
void
dns_message_puttempname(dns_message_t *msg, dns_name_t **item)
{
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(item != NULL && *item != NULL);
releasename(msg, *item);
*item = NULL;
}
void
dns_message_puttemprdata(dns_message_t *msg, dns_rdata_t **item)
{
@@ -1872,3 +1863,14 @@ dns_message_setopt(dns_message_t *msg, dns_rdataset_t *opt) {
return (DNS_R_SUCCESS);
}
void
dns_message_takebuffer(dns_message_t *msg, isc_buffer_t **buffer)
{
REQUIRE(DNS_MESSAGE_VALID(msg));
REQUIRE(buffer != NULL);
REQUIRE(ISC_BUFFER_VALID(*buffer));
ISC_LIST_APPEND(msg->cleanup, *buffer, link);
*buffer = NULL;
}