diff options
Diffstat (limited to 'src/resolve/resolved-dns-transaction.c')
-rw-r--r-- | src/resolve/resolved-dns-transaction.c | 34 |
1 files changed, 25 insertions, 9 deletions
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c index 8c4f23a4da..0e09a339aa 100644 --- a/src/resolve/resolved-dns-transaction.c +++ b/src/resolve/resolved-dns-transaction.c @@ -418,7 +418,7 @@ void dns_transaction_process_reply(DnsTransaction *t, DnsPacket *p) { case DNS_PROTOCOL_DNS: assert(t->server); - dns_server_packet_received(t->server, ts - t->start_usec); + dns_server_packet_received(t->server, t->current_features, ts - t->start_usec); break; case DNS_PROTOCOL_LLMNR: @@ -534,6 +534,9 @@ static int dns_transaction_emit(DnsTransaction *t) { if (r < 0) return r; + if (t->server) + t->current_features = t->server->possible_features; + return 0; } @@ -544,15 +547,26 @@ static int on_transaction_timeout(sd_event_source *s, usec_t usec, void *userdat assert(s); assert(t); - /* Timeout reached? Try again, with a new server */ - dns_transaction_next_dns_server(t); + /* Timeout reached? Increase the timeout for the server used */ + switch (t->scope->protocol) { + case DNS_PROTOCOL_DNS: + assert(t->server); - /* ... and possibly increased timeout */ - if (t->server) - dns_server_packet_lost(t->server, usec - t->start_usec); - else + dns_server_packet_lost(t->server, t->current_features, usec - t->start_usec); + + break; + case DNS_PROTOCOL_LLMNR: + case DNS_PROTOCOL_MDNS: dns_scope_packet_lost(t->scope, usec - t->start_usec); + break; + default: + assert_not_reached("Invalid DNS protocol."); + } + + /* ...and try again with a new server */ + dns_transaction_next_dns_server(t); + r = dns_transaction_go(t); if (r < 0) dns_transaction_complete(t, DNS_TRANSACTION_RESOURCES); @@ -734,11 +748,13 @@ int dns_transaction_go(DnsTransaction *t) { * always be made via TCP on LLMNR */ r = dns_transaction_open_tcp(t); } else { - /* Try via UDP, and if that fails due to large size try via TCP */ + /* Try via UDP, and if that fails due to large size or lack of + * support try via TCP */ r = dns_transaction_emit(t); - if (r == -EMSGSIZE) + if (r == -EMSGSIZE || r == -EAGAIN) r = dns_transaction_open_tcp(t); } + if (r == -ESRCH) { /* No servers to send this to? */ dns_transaction_complete(t, DNS_TRANSACTION_NO_SERVERS); |