]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
fix handling of '+ednsopt=:'; support 100 ednsopts per query rather than 100 total
authorMark Andrews <marka@isc.org>
Thu, 12 Jul 2018 02:38:24 +0000 (12:38 +1000)
committerMark Andrews <marka@isc.org>
Wed, 1 Aug 2018 22:55:01 +0000 (08:55 +1000)
bin/tools/mdig.c

index a5ec672cb04ca2794fc115f7da68629ceda3fb4f..00dba8635d059d4a08fe55176bd61e5540352ee3 100644 (file)
@@ -841,8 +841,21 @@ parse_xint(isc_uint32_t *uip, const char *value, isc_uint32_t max,
        return (parse_uint_helper(uip, value, max, desc, 0));
 }
 
-static dns_ednsopt_t ednsopts[EDNSOPTS];
-static unsigned char ednsoptscnt = 0;
+static void
+newopts(struct query *query) {
+        size_t len = sizeof(query->ednsopts[0]) * EDNSOPTS;
+        size_t i;
+
+        query->ednsopts = isc_mem_allocate(mctx, len);
+        if (query->ednsopts == NULL)
+                fatal("out of memory");
+
+        for (i = 0; i < EDNSOPTS; i++) {
+                query->ednsopts[i].code = 0;
+                query->ednsopts[i].length = 0;
+                query->ednsopts[i].value = NULL;
+        }
+}
 
 static void
 save_opt(struct query *query, char *code, char *value) {
@@ -850,33 +863,39 @@ save_opt(struct query *query, char *code, char *value) {
        isc_buffer_t b;
        isc_result_t result;
 
-       if (ednsoptscnt == EDNSOPTS)
+       if (query->ednsopts == NULL) {
+               newopts(query);
+       }
+
+       if (query->ednsoptscnt == EDNSOPTS) {
                fatal("too many ednsopts");
+       }
 
        result = parse_uint(&num, code, 65535, "ednsopt");
-       if (result != ISC_R_SUCCESS)
+       if (result != ISC_R_SUCCESS) {
                fatal("bad edns code point: %s", code);
+       }
 
-       ednsopts[ednsoptscnt].code = num;
-       ednsopts[ednsoptscnt].length = 0;
-       ednsopts[ednsoptscnt].value = NULL;
+       query->ednsopts[query->ednsoptscnt].code = num;
+       query->ednsopts[query->ednsoptscnt].length = 0;
+       query->ednsopts[query->ednsoptscnt].value = NULL;
 
        if (value != NULL) {
                char *buf;
                buf = isc_mem_allocate(mctx, strlen(value)/2 + 1);
-               if (buf == NULL)
+               if (buf == NULL) {
                        fatal("out of memory");
+               }
                isc_buffer_init(&b, buf, strlen(value)/2 + 1);
                result = isc_hex_decodestring(value, &b);
                CHECK("isc_hex_decodestring", result);
-               ednsopts[ednsoptscnt].value = isc_buffer_base(&b);
-               ednsopts[ednsoptscnt].length = isc_buffer_usedlength(&b);
+               query->ednsopts[query->ednsoptscnt].value =
+                                               isc_buffer_base(&b);
+               query->ednsopts[query->ednsoptscnt].length =
+                                               isc_buffer_usedlength(&b);
        }
 
-       if (query->ednsoptscnt == 0)
-               query->ednsopts = &ednsopts[ednsoptscnt];
        query->ednsoptscnt++;
-       ednsoptscnt++;
 }
 
 static isc_result_t
@@ -1263,11 +1282,19 @@ plus_option(char *option, struct query *query, isc_boolean_t global)
                                                        query->ednsoptscnt = 0;
                                                        break;
                                                }
-                                               if (value == NULL)
+                                               code = NULL;
+                                               if (value != NULL) {
+                                                       code = strtok_r(value,
+                                                                       ":",
+                                                                       &last);
+                                               }
+                                               if (code == NULL) {
                                                        fatal("ednsopt no "
                                                              "code point "
                                                              "specified");
-                                               code = strtok_r(value, ":", &last);
+                                               }
+                                               value = strtok_r(NULL, "\0",
+                                                                &last);
                                                save_opt(query, code, value);
                                                break;
                                        default:
@@ -1896,6 +1923,7 @@ main(int argc, char *argv[]) {
        dns_dispatch_t *dispatchvx;
        dns_view_t *view;
        int ns;
+       unsigned int i;
 
        RUNCHECK(isc_app_start());
 
@@ -1991,6 +2019,15 @@ main(int argc, char *argv[]) {
        while (query != NULL) {
                struct query *next = ISC_LIST_NEXT(query, link);
 
+               if (query->ednsopts != NULL) {
+                       for (i = 0; i < EDNSOPTS; i++) {
+                               if (query->ednsopts[i].value != NULL) {
+                                       isc_mem_free(mctx,
+                                                    query->ednsopts[i].value);
+                               }
+                       }
+                       isc_mem_free(mctx, query->ednsopts);
+               }
                if (query->ecs_addr != NULL) {
                        isc_mem_free(mctx, query->ecs_addr);
                        query->ecs_addr = NULL;