return (looknew);
}
+#define EDNSOPT_OPTIONS 100U
+
+static void
+cloneopts(dig_lookup_t *looknew, dig_lookup_t *lookold) {
+ size_t len = sizeof(looknew->ednsopts[0]) * EDNSOPT_OPTIONS;
+ size_t i;
+ looknew->ednsopts = isc_mem_allocate(mctx, len);
+ if (looknew->ednsopts == NULL)
+ fatal("out of memory");
+ for (i = 0; i < EDNSOPT_OPTIONS; i++) {
+ looknew->ednsopts[i].code = 0;
+ looknew->ednsopts[i].length = 0;
+ looknew->ednsopts[i].value = NULL;
+ }
+ looknew->ednsoptscnt = 0;
+ if (lookold == NULL || lookold->ednsopts == NULL)
+ return;
+
+ for (i = 0; i < lookold->ednsoptscnt; i++) {
+ len = lookold->ednsopts[i].length;
+ if (len != 0) {
+ INSIST(lookold->ednsopts[i].value != NULL);
+ looknew->ednsopts[i].value =
+ isc_mem_allocate(mctx, len);
+ if (looknew->ednsopts[i].value == NULL)
+ fatal("out of memory");
+ memmove(looknew->ednsopts[i].value,
+ lookold->ednsopts[i].value, len);
+ }
+ looknew->ednsopts[i].code = lookold->ednsopts[i].code;
+ looknew->ednsopts[i].length = len;
+ }
+ looknew->ednsoptscnt = lookold->ednsoptscnt;
+}
+
/*%
* Clone a lookup, perhaps copying the server list. This does not clone
* the query list, since it will be regenerated by the setup_lookup()
looknew->seenbadcookie = lookold->seenbadcookie;
looknew->badcookie = lookold->badcookie;
looknew->cookie = lookold->cookie;
- looknew->ednsopts = lookold->ednsopts;
- looknew->ednsoptscnt = lookold->ednsoptscnt;
+ if (lookold->ednsopts != NULL) {
+ cloneopts(looknew, lookold);
+ } else {
+ looknew->ednsopts = NULL;
+ looknew->ednsoptscnt = 0;
+ }
looknew->ednsneg = lookold->ednsneg;
looknew->mapped = lookold->mapped;
looknew->idnout = lookold->idnout;
check_result(result, "isc_mutex_init");
}
-#define EDNSOPTS 100U
-static dns_ednsopt_t ednsopts[EDNSOPTS];
-static unsigned char ednsoptscnt = 0;
-
typedef struct dig_ednsoptname {
isc_uint32_t code;
const char *name;
isc_boolean_t found = ISC_FALSE;
unsigned int i;
- if (ednsoptscnt == EDNSOPTS)
+ if (lookup->ednsoptscnt >= EDNSOPT_OPTIONS)
fatal("too many ednsopts");
for (i = 0; i < N_EDNS_OPTNAMES; i++) {
fatal("bad edns code point: %s", code);
}
- ednsopts[ednsoptscnt].code = num;
- ednsopts[ednsoptscnt].length = 0;
- ednsopts[ednsoptscnt].value = NULL;
+ if (lookup->ednsopts == NULL) {
+ cloneopts(lookup, NULL);
+ }
+
+ if (lookup->ednsopts[lookup->ednsoptscnt].value != NULL)
+ isc_mem_free(mctx, lookup->ednsopts[lookup->ednsoptscnt].value);
+
+ lookup->ednsopts[lookup->ednsoptscnt].code = num;
+ lookup->ednsopts[lookup->ednsoptscnt].length = 0;
+ lookup->ednsopts[lookup->ednsoptscnt].value = NULL;
if (value != NULL) {
char *buf;
isc_buffer_init(&b, buf, (unsigned int) strlen(value)/2 + 1);
result = isc_hex_decodestring(value, &b);
check_result(result, "isc_hex_decodestring");
- ednsopts[ednsoptscnt].value = isc_buffer_base(&b);
- ednsopts[ednsoptscnt].length = isc_buffer_usedlength(&b);
+ lookup->ednsopts[lookup->ednsoptscnt].value =
+ isc_buffer_base(&b);
+ lookup->ednsopts[lookup->ednsoptscnt].length =
+ isc_buffer_usedlength(&b);
}
- if (lookup->ednsoptscnt == 0)
- lookup->ednsopts = &ednsopts[ednsoptscnt];
lookup->ednsoptscnt++;
- ednsoptscnt++;
}
/*%
if (lookup->ecs_addr != NULL)
isc_mem_free(mctx, lookup->ecs_addr);
+ if (lookup->ednsopts != NULL) {
+ size_t i;
+ for (i = 0; i < EDNSOPT_OPTIONS; i++) {
+ if (lookup->ednsopts[i].value != NULL)
+ isc_mem_free(mctx, lookup->ednsopts[i].value);
+ }
+ isc_mem_free(mctx, lookup->ednsopts);
+ }
+
isc_mem_free(mctx, lookup);
}
if (lookup->udpsize > 0 || lookup->dnssec ||
lookup->edns > -1 || lookup->ecs_addr != NULL)
{
- dns_ednsopt_t opts[EDNSOPTS + DNS_EDNSOPTIONS];
+#define MAXOPTS (EDNSOPT_OPTIONS + DNS_EDNSOPTIONS)
+ dns_ednsopt_t opts[MAXOPTS];
unsigned int flags;
- int i = 0;
+ unsigned int i = 0;
if (lookup->udpsize == 0)
lookup->udpsize = 4096;
lookup->edns = 0;
if (lookup->nsid) {
- INSIST(i < DNS_EDNSOPTIONS);
+ INSIST(i < MAXOPTS);
opts[i].code = DNS_OPT_NSID;
opts[i].length = 0;
opts[i].value = NULL;
/* Round up prefix len to a multiple of 8 */
addrl = (plen + 7) / 8;
- INSIST(i < DNS_EDNSOPTIONS);
+ INSIST(i < MAXOPTS);
opts[i].code = DNS_OPT_CLIENT_SUBNET;
opts[i].length = (isc_uint16_t) addrl + 4;
check_result(result, "isc_buffer_allocate");
}
if (lookup->sendcookie) {
- INSIST(i < DNS_EDNSOPTIONS);
+ INSIST(i < MAXOPTS);
opts[i].code = DNS_OPT_COOKIE;
if (lookup->cookie != NULL) {
isc_buffer_init(&b, cookiebuf,
}
if (lookup->expire) {
- INSIST(i < DNS_EDNSOPTIONS);
+ INSIST(i < MAXOPTS);
opts[i].code = DNS_OPT_EXPIRE;
opts[i].length = 0;
opts[i].value = NULL;
}
if (lookup->ednsoptscnt != 0) {
+ INSIST(i + lookup->ednsoptscnt <= MAXOPTS);
memmove(&opts[i], lookup->ednsopts,
sizeof(dns_ednsopt_t) * lookup->ednsoptscnt);
i += lookup->ednsoptscnt;
debug("Removing log context");
isc_log_destroy(&lctx);
- while (ednsoptscnt > 0U) {
- ednsoptscnt--;
- if (ednsopts[ednsoptscnt].value != NULL)
- isc_mem_free(mctx, ednsopts[ednsoptscnt].value);
- }
-
debug("Destroy memory");
if (memdebugging != 0)
isc_mem_stats(mctx, stderr);