diff options
author | Dave Barach <dave@barachs.net> | 2018-01-09 17:00:00 -0500 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2018-01-10 02:43:07 +0000 |
commit | 580eda7067bee891c00f59fe3927720def3837ec (patch) | |
tree | cf62ee4dd55c6c61adcff15917ab23059f02b17c /src/vnet/dns/resolver_process.c | |
parent | aec8f8984771cabc79a8ed64f56afcf61465d00a (diff) |
Functional improvements, bug fixes
At least when testing against "known good" DNS servers: it turns out
that sending 2x requests - one for an A-record and another for a
AAAA-record - seems to work better than sending a single DNS_TYPE_ALL
request.
Fix c-string vs. u8 vector mistakes. Fix server failover.
Change-Id: I26554f0a9c1744376f21372506ebec8658e351e2
Signed-off-by: Dave Barach <dave@barachs.net>
Diffstat (limited to 'src/vnet/dns/resolver_process.c')
-rw-r--r-- | src/vnet/dns/resolver_process.c | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/src/vnet/dns/resolver_process.c b/src/vnet/dns/resolver_process.c index 47d8a95ea16..5f43fada983 100644 --- a/src/vnet/dns/resolver_process.c +++ b/src/vnet/dns/resolver_process.c @@ -86,12 +86,69 @@ resolve_event (dns_main_t * dm, f64 now, u8 * reply) vec_free (ep->dns_response); /* Handle [sic] recursion AKA CNAME indirection */ - if (vnet_dns_cname_indirection_nolock (dm, pool_index, reply)) + rv = vnet_dns_cname_indirection_nolock (dm, pool_index, reply); + + /* CNAME found, further resolution pending, we're done here */ + if (rv > 0) + { + dns_cache_unlock (dm); + return; + } + /* Server backfire: refused to answer, or sent zero replies */ + if (rv < 0) { + /* Try a different server */ + if (ep->server_af /* ip6 */ ) + { + if (0) + clib_warning ("Server %U failed to resolve '%s'", + format_ip6_address, + dm->ip6_name_servers + ep->server_rotor, ep->name); + /* Any more servers to try? */ + if (ep->server_fails > 1 || vec_len (dm->ip6_name_servers) <= 1) + { + /* No, tell the client to go away */ + goto reply; + } + ep->retry_count = 0; + ep->server_rotor++; + ep->server_fails++; + if (ep->server_rotor >= vec_len (dm->ip6_name_servers)) + ep->server_rotor = 0; + if (0) + clib_warning ("Try server %U", format_ip6_address, + dm->ip6_name_servers + ep->server_rotor); + vnet_dns_send_dns6_request + (dm, ep, dm->ip6_name_servers + ep->server_rotor); + } + else + { + if (0) + clib_warning ("Server %U failed to resolve '%s'", + format_ip4_address, + dm->ip4_name_servers + ep->server_rotor, ep->name); + + if (ep->server_fails > 1 || vec_len (dm->ip4_name_servers) <= 1) + { + /* No, tell the client to go away */ + goto reply; + } + ep->retry_count = 0; + ep->server_rotor++; + ep->server_fails++; + if (ep->server_rotor >= vec_len (dm->ip4_name_servers)) + ep->server_rotor = 0; + if (0) + clib_warning ("Try server %U", format_ip4_address, + dm->ip4_name_servers + ep->server_rotor); + vnet_dns_send_dns4_request + (dm, ep, dm->ip4_name_servers + ep->server_rotor); + } dns_cache_unlock (dm); return; } +reply: /* Save the response */ ep->dns_response = reply; /* Pick some sensible default. */ |