]> git.ipfire.org Git - thirdparty/knot-resolver.git/commitdiff
selection: support custom port when forwarding
authorŠtěpán Balážik <stepan.balazik@nic.cz>
Thu, 3 Sep 2020 08:49:34 +0000 (10:49 +0200)
committerŠtěpán Balážik <stepan.balazik@nic.cz>
Thu, 15 Oct 2020 11:22:21 +0000 (13:22 +0200)
lib/selection.c
lib/selection.h
lib/selection_forward.c
lib/selection_iter.c

index 45db72a21d31a275f9b978e6f95b18ca39626a51..c89991095b7761ecd6f3b5b3dac139f2dee9eca9 100644 (file)
@@ -235,21 +235,22 @@ struct kr_transport *choose_transport(struct choice choices[],
 
 
        int port;
-       switch (transport->protocol)
-       {
-       case KR_TRANSPORT_TLS:
-               port = KR_DNS_TLS_PORT;
-               break;
-       case KR_TRANSPORT_UDP:
-       case KR_TRANSPORT_TCP:
-               port = KR_DNS_PORT;
-               break;
-       default:
-               assert(0);
-               break;
+       if (!(port = choices[choice].port)) {
+               switch (transport->protocol)
+               {
+               case KR_TRANSPORT_TLS:
+                       port = KR_DNS_TLS_PORT;
+                       break;
+               case KR_TRANSPORT_UDP:
+               case KR_TRANSPORT_TCP:
+                       port = KR_DNS_PORT;
+                       break;
+               default:
+                       assert(0);
+                       break;
+               }
        }
 
-
        switch (choices[choice].address_len)
        {
        case sizeof(struct in_addr):
index 30d6add2c6c032a7aeb6a7ffec076c93173967c8..58830259f16b90419532908ded39cfd1dada0fd9 100644 (file)
@@ -85,11 +85,12 @@ struct address_state {
        int errors[KR_SELECTION_NUMBER_OF_ERRORS];
 };
 
-// Array of these is one of inputs for the actual selection algorithm (`iter_get_best_transport`)
+// Array of these is one of inputs for the actual selection algorithm (`choose_transport`)
 struct choice {
        uint8_t *address;
        size_t address_len;
        struct address_state *address_state;
+       uint16_t port; // used to overwrite the port number; if zero, `choose_transport` determines it
 };
 
 struct kr_transport *choose_transport(struct choice choices[],
index 1f35852913fdf6c3d4a3f029ba7deca4a573fa4f..f491707a8e02cdee3676a5f86e92f68318f82e44 100644 (file)
@@ -35,11 +35,14 @@ void forward_choose_transport(struct kr_query *qry, struct kr_transport **transp
        for (int i = 0; i < local_state->target_num; i++) {
                union inaddr *address = &local_state->targets[i];
                size_t addr_len;
+               uint16_t port;
                switch (address->ip.sa_family) {
                        case AF_INET:
+                               port = ntohs(address->ip4.sin_port);
                                addr_len = sizeof(struct in_addr);
                                break;
                        case AF_INET6:
+                               port = ntohs(address->ip6.sin6_port);
                                addr_len = sizeof(struct in6_addr);
                                break;
                        default:
@@ -67,6 +70,7 @@ void forward_choose_transport(struct kr_query *qry, struct kr_transport **transp
                        .address = ip_to_bytes(address, addr_len),
                        .address_len = addr_len,
                        .address_state = addr_state,
+                       .port = port,
                };
        }
 
index de190c1ba3dc33a571b2f74b48be40027aadcce4..59e17f5c8800dd9a4b7de45f5199ddf0ed3bb8ee 100644 (file)
@@ -164,9 +164,11 @@ void iter_choose_transport(struct kr_query *qry, struct kr_transport **transport
                uint8_t* address = (uint8_t *)trie_it_key(it, &address_len);
                struct address_state *address_state = (struct address_state *)*trie_it_val(it);
                if (address_state->generation == local_state->generation) {
-                       choices[valid_addresses].address = address;
-                       choices[valid_addresses].address_len = address_len;
-                       choices[valid_addresses].address_state = address_state;
+                       choices[valid_addresses] = (struct choice){
+                               .address = address,
+                               .address_len = address_len,
+                               .address_state = address_state,
+                       };
                        valid_addresses++;
                }