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):
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[],
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:
.address = ip_to_bytes(address, addr_len),
.address_len = addr_len,
.address_state = addr_state,
+ .port = port,
};
}
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++;
}