diff --git a/lib/selection.c b/lib/selection.c index 8031fb74db2470589e7b9f41ce05d46cf56ae0e1..d6ef22fbf0810550b2e1fed8d09634ab5df3a2f2 100644 --- a/lib/selection.c +++ b/lib/selection.c @@ -125,6 +125,7 @@ void bytes_to_ip(uint8_t *bytes, size_t len, uint16_t port, union inaddr *dst) dst->ip4.sin_port = htons(port); break; case sizeof(struct in6_addr): + memset(&dst->ip6, 0, sizeof(dst->ip6)); // avoid uninit surprises dst->ip6.sin6_family = AF_INET6; memcpy(&dst->ip6.sin6_addr, bytes, len); dst->ip6.sin6_port = htons(port); @@ -246,19 +247,18 @@ static void check_network_settings(struct address_state *address_state, } } -void update_address_state(struct address_state *state, uint8_t *address, +void update_address_state(struct address_state *state, union inaddr *address, size_t address_len, struct kr_query *qry) { - union inaddr tmp_address; - bytes_to_ip(address, address_len, 0, &tmp_address); - check_tls_capable(state, qry->request, &tmp_address.ip); + check_tls_capable(state, qry->request, &address->ip); /* TODO: uncomment this once we actually use the information it collects check_tcp_connections(address_state, qry->request, &tmp_address.ip); */ check_network_settings(state, address_len, qry->flags.NO_IPV4, qry->flags.NO_IPV6); state->rtt_state = - get_rtt_state(address, address_len, &qry->request->ctx->cache); + get_rtt_state(ip_to_bytes(address, address_len), + address_len, &qry->request->ctx->cache); invalidate_dead_upstream( state, qry->request->ctx->cache_rtt_tout_retry_interval); #ifdef SELECTION_CHOICE_LOGGING @@ -403,11 +403,25 @@ struct kr_transport *select_transport(struct choice choices[], int choices_len, break; default: assert(0); - break; + return NULL; } } - bytes_to_ip(chosen->address, chosen->address_len, port, &transport->address); + switch (chosen->address_len) + { + case sizeof(struct in_addr): + transport->address.ip4 = chosen->address.ip4; + transport->address.ip4.sin_port = htons(port); + break; + case sizeof(struct in6_addr): + transport->address.ip6 = chosen->address.ip6; + transport->address.ip6.sin6_port = htons(port); + break; + default: + assert(0); + return NULL; + } + transport->address_len = chosen->address_len; if (choice_index) { diff --git a/lib/selection.h b/lib/selection.h index 113a468bf22a2522f1d70f6b945ce37f193d5392..18cefccc26ddfce61a6119d83fdb003c7b1c9ff3 100644 --- a/lib/selection.h +++ b/lib/selection.h @@ -164,7 +164,7 @@ struct address_state { * @brief Array of these is one of inputs for the actual selection algorithm (`select_transport`) */ struct choice { - uint8_t *address; + union inaddr address; size_t address_len; struct address_state *address_state; /** used to overwrite the port number; @@ -240,5 +240,5 @@ uint8_t *ip_to_bytes(const union inaddr *src, size_t len); /** * @internal Fetch per-address information from various sources. */ -void update_address_state(struct address_state *state, uint8_t *address, +void update_address_state(struct address_state *state, union inaddr *address, size_t address_len, struct kr_query *qry); diff --git a/lib/selection_forward.c b/lib/selection_forward.c index d741410067d46ab6464a8019a047546b52f53ab3..b311fc9f95752cedb297bb6c550fead23b8a303a 100644 --- a/lib/selection_forward.c +++ b/lib/selection_forward.c @@ -59,8 +59,7 @@ void forward_choose_transport(struct kr_query *qry, struct address_state *addr_state = &local_state->addr_states[i]; addr_state->ns_name = (knot_dname_t *)""; - update_address_state(addr_state, ip_to_bytes(address, addr_len), - addr_len, qry); + update_address_state(addr_state, address, addr_len, qry); if (addr_state->generation == -1) { continue; @@ -68,7 +67,7 @@ void forward_choose_transport(struct kr_query *qry, addr_state->choice_array_index = i; choices[valid++] = (struct choice){ - .address = ip_to_bytes(address, addr_len), + .address = *address, .address_len = addr_len, .address_state = addr_state, .port = port, diff --git a/lib/selection_iter.c b/lib/selection_iter.c index 4e8642d7aea16c5007cd46bb35bebe0530e18c73..388f29f8ea85941daa9a3b5789d4014ce3214d4d 100644 --- a/lib/selection_iter.c +++ b/lib/selection_iter.c @@ -124,7 +124,9 @@ static void unpack_state_from_zonecut(struct iter_local_state *local_state, } else if (address_len == sizeof(struct in6_addr)) { name_state->aaaa_state = RECORD_RESOLVED; } - update_address_state(address_state, address, address_len, qry); + union inaddr tmp_address; + bytes_to_ip(address, address_len, 0, &tmp_address); + update_address_state(address_state, &tmp_address, address_len, qry); } } trie_it_free(it); @@ -143,10 +145,10 @@ static int get_valid_addresses(struct iter_local_state *local_state, if (address_state->generation == local_state->generation && !address_state->unrecoverable_errors) { choices[count] = (struct choice){ - .address = address, .address_len = address_len, .address_state = address_state, }; + bytes_to_ip(address, address_len, 0, &choices[count].address); count++; } }