message.c revision c7868e2262d57451c7f0ce246be5f44e8c33f1e0
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * Copyright (C) 1999, 2000 Internet Software Consortium.
ec5347e2c775f027573ce5648b910361aa926c01Automatic Updater * Permission to use, copy, modify, and distribute this software for any
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley * purpose with or without fee is hereby granted, provided that the above
c46bcd7c6908745e19b0b1fe18a23bbaaee553edBob Halley * copyright notice and this permission notice appear in all copies.
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
dafcb997e390efa4423883dafd100c975c4095d6Mark Andrews * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
5d9cd26d79773c0014554a70972a24bc76aa4796Andreas Gustafsson#include <isc/string.h> /* Required for HP/UX (and others?) */
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence#define DNS_MESSAGE_EDNSVERSION_MASK 0x00ff0000U
113b83a9e26c1f0b9d99d9b659306907f5621750Andreas Gustafsson#define VALID_NAMED_SECTION(s) (((s) > DNS_SECTION_ANY) \
ca42dcc0686fefd3db202edab80e5adb09d6add5Evan Hunt#define VALID_SECTION(s) (((s) >= DNS_SECTION_ANY) \
113b83a9e26c1f0b9d99d9b659306907f5621750Andreas Gustafsson#define ADD_STRING(b, s) {if (strlen(s) >= \
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews#define VALID_PSEUDOSECTION(s) (((s) >= DNS_PSEUDOSECTION_ANY) \
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews * This is the size of each individual scratchpad buffer, and the numbers
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews * of various block allocations used within the server.
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews * XXXMLG These should come from a config setting.
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews * Text representation of the different items, for message_totext
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews * functions.
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrewsstatic char *sectiontext[] = {
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews "AUTHORITY",
93d6dfaf66258337985427c86181f01fc51f0bb4Mark Andrews "ADDITIONAL"
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrewsstatic char *opcodetext[] = {
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews "RESERVED3",
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews "RESERVED6",
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews "RESERVED7",
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews "RESERVED8",
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews "RESERVED9",
a5d43b72413db3edd6b36a58f9bdf2cf6ff692f2Bob Halley "RESERVED10",
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence "RESERVED11",
ca42dcc0686fefd3db202edab80e5adb09d6add5Evan Hunt "RESERVED12",
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews "RESERVED13",
e7fb847ed570dd8c1bcdacabb3d69bd81feb79aeMark Andrews "RESERVED14",
96d3f5b8ca61f7b59365d68e26aa923d13a0846bBob Halley "RESERVED15"
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic char *rcodetext[] = {
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence "RESERVED11",
a3ab70dae26d009bf78b0594b2ab5eb9208f4b91Michael Graff "RESERVED12",
54d47fb18b5ee4d36d6ef77e379501f6cbe2f23cDavid Lawrence "RESERVED13",
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence "RESERVED14",
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence "RESERVED15",
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence * "helper" type, which consists of a block of some type, and is linkable.
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence * For it to work, sizeof(dns_msgblock_t) must be a multiple of the pointer
fc80027fb54b501cdd88461bf879d078259e0226David Lawrence * size, or the allocated elements will not be alligned correctly.
56b40c0185bcbd4a04422acc1211b5e2d2ba8a3eBob Halley unsigned int count;
56b40c0185bcbd4a04422acc1211b5e2d2ba8a3eBob Halley unsigned int remaining;
56b40c0185bcbd4a04422acc1211b5e2d2ba8a3eBob Halley}; /* dynamically sized */
56b40c0185bcbd4a04422acc1211b5e2d2ba8a3eBob Halleymsgblock_allocate(isc_mem_t *, unsigned int, unsigned int);
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉 ((type *)msgblock_internalget(block, sizeof(type)))
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉static inline void *
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉msgblock_internalget(dns_msgblock_t *, unsigned int);
8dd17056ff254ed8ce429843bada5621f786d257Michael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffstatic inline void
64828244e04e86dfa40f0a4f0c05f27923da499dMichael Graffmsgblock_free(isc_mem_t *, dns_msgblock_t *, unsigned int);
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉 * Allocate a new dns_msgblock_t, and return a pointer to it. If no memory
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉 * is free, return NULL.
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉msgblock_allocate(isc_mem_t *mctx, unsigned int sizeof_type,
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉 length = sizeof(dns_msgblock_t) + (sizeof_type * count);
20eb22375f52b35105fa36263f83f116b580eba8Bob Halley * Return an element from the msgblock. If no more are available, return
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsstatic inline void *
2d80f690e0b5f9d7494448cf844e2f178419d6e9Bob Halleymsgblock_internalget(dns_msgblock_t *block, unsigned int sizeof_type) {
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsstatic inline void
9e4292a2b46bc30568bd1eb204761f7134609405David Lawrence * Release memory associated with a message block.
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsstatic inline void
74da616f07f038138ddd45c10fc8de0920244d12Michael Graffmsgblock_free(isc_mem_t *mctx, dns_msgblock_t *block, unsigned int sizeof_type)
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews unsigned int length;
5c14b1acbe0e7d244fbebbe5a16cea29233d79a3Michael Graff length = sizeof(dns_msgblock_t) + (sizeof_type * block->count);
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews * Allocate a new dynamic buffer, and attach it to this message as the
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrews * "current" buffer. (which is always the last on the list, for our
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsnewbuffer(dns_message_t *msg, unsigned int size) {
adde4612541b23d82b00741563ef84cb5192df8cMichael Graff result = isc_buffer_allocate(msg->mctx, &dynbuf, size);
adde4612541b23d82b00741563ef84cb5192df8cMichael Graff ISC_LIST_APPEND(msg->scratchpad, dynbuf, link);
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrewsstatic inline void
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsreleaserdata(dns_message_t *msg, dns_rdata_t *rdata) {
adde4612541b23d82b00741563ef84cb5192df8cMichael Graff ISC_LIST_PREPEND(msg->freerdata, rdata, link);
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsstatic inline dns_rdata_t *
3ff55a3111fe09f517218905248974b8319b2c59Mark Andrews msgblock = msgblock_allocate(msg->mctx, sizeof(dns_rdata_t),
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrewsstatic inline void
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsreleaserdatalist(dns_message_t *msg, dns_rdatalist_t *rdatalist) {
658c72a46ee3b1193cc38e4f94121e344e0751e9Mark Andrews ISC_LIST_PREPEND(msg->freerdatalist, rdatalist, link);
f4cbe536b11da614fe05aeaeff41e324854cda7bMark Andrews ISC_LIST_UNLINK(msg->freerdatalist, rdatalist, link);
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrews rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrews ISC_LIST_APPEND(msg->rdatalists, msgblock, link);
f40036cbd6ba047c954dcea8705a0b9392d403d9Mark Andrews rdatalist = msgblock_get(msgblock, dns_rdatalist_t);
9f7d51ee3290e2a064d71016a6bd555b47134a7cMark Andrewsstatic inline void
d3397876060db0baa38432d90283eda6097f608dBob Halleystatic inline void
fd088dc8c8e63f495c4d0257f21849542a582c1eDavid Lawrence unsigned int i;
a27fe4c990f96bd792f2a07ca4d38c78d5b9df2cTatuya JINMEI 神明達哉 for (i = 0; i < DNS_SECTION_MAX; i++) {
m->opt_reserved = 0;
m->reserved = 0;
m->need_cctx_cleanup = 0;
msginitheader(m);
msginitprivate(m);
msginittsig(m);
m->header_ok = 0;
m->question_ok = 0;
m->tcp_continuation = 0;
m->verified_sig = 0;
m->verify_attempted = 0;
if (!everything) {
if (!everything) {
sizeof(dns_rdata_any_tsig_t));
sizeof(dns_rdata_any_tsig_t));
if (!everything)
dns_message_t *m;
if (m == NULL)
return (ISC_R_NOMEMORY);
msginit(m);
for (i = 0 ; i < DNS_SECTION_MAX ; i++)
goto cleanup;
&m->rdspool);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
*msgp = m;
return (ISC_R_SUCCESS);
m->magic = 0;
return (ISC_R_NOMEMORY);
static isc_result_t
return (ISC_R_SUCCESS);
return (ISC_R_NOTFOUND);
return (ISC_R_SUCCESS);
return (ISC_R_NOTFOUND);
static isc_result_t
unsigned int tries;
tries = 0;
scratch);
tries++;
return (result);
return (result);
return (ISC_R_UNEXPECTED);
static isc_result_t
unsigned int tries;
unsigned int trysize;
return (ISC_R_SUCCESS);
tries = 0;
trysize = 0;
scratch);
if (tries == 0) {
return (ISC_R_NOSPACE);
tries++;
return (result);
return (result);
static isc_result_t
isc_region_t r;
unsigned int count;
return (ISC_R_NOMEMORY);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
return (ISC_R_SUCCESS);
if (free_name)
return (result);
static isc_result_t
isc_region_t r;
return (ISC_R_NOMEMORY);
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
goto cleanup;
attributes = 0;
goto cleanup;
else if (covers == 0 &&
goto cleanup;
covers = 0;
goto cleanup;
&rdataset);
goto cleanup;
goto cleanup;
goto cleanup;
unsigned int ercode;
return (ISC_R_SUCCESS);
if (free_name)
if (free_rdataset)
return (result);
isc_region_t r;
return (ISC_R_UNEXPECTEDEND);
return (ret);
return (ret);
return (ret);
return (ret);
if (r.length != 0)
return (DNS_R_FORMERR);
return (ISC_R_NOMEMORY);
sizeof(isc_region_t));
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
isc_region_t r;
return (result);
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
isc_region_t r;
return (ISC_R_NOSPACE);
return (ISC_R_SUCCESS);
static inline isc_boolean_t
int pass_needed;
return (ISC_FALSE);
case dns_rdatatype_a:
case dns_rdatatype_aaaa:
case dns_rdatatype_a6:
case dns_rdatatype_sig:
case dns_rdatatype_key:
return (ISC_FALSE);
return (ISC_TRUE);
unsigned int options)
int pass;
total = 0;
return (ISC_R_SUCCESS);
DNS_RDATASETATTR_RENDERED) != 0)
goto next;
goto next;
count = 0;
&count);
return (result);
next:
} while (--pass != 0);
return (ISC_R_SUCCESS);
isc_region_t r;
isc_region_t r;
int result;
unsigned int count;
return (DNS_R_FORMERR);
count = 0;
return (result);
return (result);
count = 0;
return (result);
return (result);
count = 0;
return (result);
return (ISC_R_SUCCESS);
for (i = 0; i < DNS_SECTION_MAX; i++) {
return (ISC_R_NOMORE);
return (ISC_R_SUCCESS);
return (ISC_R_NOMORE);
return (ISC_R_SUCCESS);
unsigned int attributes;
attributes = 0;
return (DNS_R_NXDOMAIN);
return (result);
return (ISC_R_SUCCESS);
return (DNS_R_NXRRSET);
return (result);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
return (ISC_R_NOMEMORY);
return (ISC_R_SUCCESS);
unsigned int *flagsp)
isc_region_t r;
unsigned int flags;
return (ISC_R_UNEXPECTEDEND);
return (ISC_R_SUCCESS);
unsigned int first_section;
return (DNS_R_FORMERR);
if (want_question_section) {
return (DNS_R_FORMERR);
return (ISC_R_SUCCESS);
return (result);
return (result);
return (ISC_R_SUCCESS);
return (NULL);
isc_region_t r;
return (ISC_R_NOTFOUND);
return (DNS_R_NOTVERIFIEDYET);
return (result);
return (result);
return (result);
return (ISC_R_SUCCESS);
return (ISC_R_UNEXPECTEDEND);
return (result);
dns_rdatatype_key, 0, 0,
goto freesig;
goto freesig;
return (result);
return ISC_R_SUCCESS;
return (result);
if (no_rdata)
target);
return (result);
return (result);
switch (section) {
case DNS_PSEUDOSECTION_OPT:
return (ISC_R_SUCCESS);
return (ISC_R_SUCCESS);
case DNS_PSEUDOSECTION_TSIG:
return (ISC_R_SUCCESS);
return (result);
case DNS_PSEUDOSECTION_SIG0:
return (ISC_R_SUCCESS);
return (result);
return (ISC_R_UNEXPECTED);
return (result);
return (result);
return (result);
return (result);
return (result);
return (result);
return (result);
return (ISC_R_SUCCESS);