Skip to content
Snippets Groups Projects
Commit f032e5ec authored by Štěpán Balážik's avatar Štěpán Balážik
Browse files

lib/selection{,_iter}.c: allow switching back to UDP

Switching to TCP instead of querying very slow servers over UDP has had
unwanted side effect – we would sometimes get stuck with a server
permanently switched to TCP. And if the server happens to not reply over
TCP we were in trouble.

Therefore after we TCP connect fails or timeouts we provide one last
chance for the server over UDP. This will not prevent the next request
to try TCP again on this server again, but we don't care because
DNS MUST ******* work over TCP.
parent 34b92c92
No related branches found
No related tags found
1 merge request!1140lib/selection{,_iter}.c: allow switching back to UDP
Pipeline #76845 failed
......@@ -230,7 +230,7 @@ static void check_tls_capable(struct address_state *address_state,
/* TODO: uncomment these once we actually use the information it collects. */
/**
* Check if there is a existing TCP connection to this address.
*
*
* @p req has to have the selection_context properly initiazed.
*/
void check_tcp_connections(struct address_state *address_state, struct kr_request *req, struct sockaddr *address) {
......@@ -567,6 +567,11 @@ void error(struct kr_query *qry, struct address_state *addr_state,
qry->flags.NO_MINIMIZE = true;
}
break;
case KR_SELECTION_TCP_CONNECT_FAILED:
case KR_SELECTION_TCP_CONNECT_TIMEOUT:
qry->server_selection.local_state->force_udp = true;
qry->flags.NO_0X20 = false;
break;
case KR_SELECTION_NOTIMPL:
case KR_SELECTION_OTHER_RCODE:
case KR_SELECTION_DNSSEC_ERROR:
......@@ -576,8 +581,6 @@ void error(struct kr_query *qry, struct address_state *addr_state,
addr_state->broken = true;
break;
case KR_SELECTION_TLS_HANDSHAKE_FAILED:
case KR_SELECTION_TCP_CONNECT_FAILED:
case KR_SELECTION_TCP_CONNECT_TIMEOUT:
/* These might get resolved by retrying. */
break;
default:
......@@ -587,7 +590,7 @@ void error(struct kr_query *qry, struct address_state *addr_state,
addr_state->error_count++;
addr_state->errors[sel_error]++;
WITH_VERBOSE(qry)
{
KR_DNAME_GET_STR(ns_name, transport->ns_name);
......
......@@ -81,6 +81,8 @@ struct local_state {
/** Force resolution of a new NS name (if possible)
* Done by selection.c:error in some cases. */
bool force_resolve;
/** Used to work around auths with broken TCP. */
bool force_udp;
void *private; /**< Inner state of the implementation.*/
};
......
......@@ -99,7 +99,7 @@ static void unpack_state_from_zonecut(struct iter_local_state *local_state,
name_state->a_state = RECORD_UNKNOWN;
name_state->aaaa_state = RECORD_UNKNOWN;
}
/* Iterate over all addresses of this NS (if any). */
for (uint8_t *obj = pack_head(*addresses); obj != pack_tail(*addresses);
obj = pack_obj_next(obj)) {
......@@ -284,6 +284,14 @@ void iter_choose_transport(struct kr_query *qry, struct kr_transport **transport
assert(0);
break;
}
if (*transport &&
(*transport)->protocol==KR_TRANSPORT_TCP &&
!qry->server_selection.local_state->truncated &&
qry->server_selection.local_state->force_udp) {
// Last chance on broken TCP.
(*transport)->protocol = KR_TRANSPORT_UDP;
}
}
if (*transport == NULL && local_state->last_error == KR_SELECTION_DNSSEC_ERROR) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment