From 1298b7bbae82f24ac3821c5df9eb7af77cee37bf Mon Sep 17 00:00:00 2001 From: bert hubert Date: Tue, 16 Oct 2018 23:14:06 +0200 Subject: [PATCH] implement 'dot' debugging output, fix crash if you explicitly queried a CNAME (thanks Marco Davids), strictly test NS glue now --- tdns/tres.cc | 58 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 47 insertions(+), 11 deletions(-) diff --git a/tdns/tres.cc b/tdns/tres.cc index 8c5935b..c5369cf 100644 --- a/tdns/tres.cc +++ b/tdns/tres.cc @@ -1,4 +1,4 @@ -#include +#include #include #include #include @@ -19,6 +19,8 @@ multimap g_root; unsigned int g_numqueries; bool g_skipIPv6{false}; //!< set this if you have no functioning IPv6 +ofstream g_dot; + /** Helper function that extracts a useable IP address from an A or AAAA resource record. Returns sin_family == 0 if it didn't work */ static ComboAddress getIP(const std::unique_ptr& rr) @@ -170,6 +172,29 @@ static auto randomizeServers(const multimap& mservers) return servers; } +static void dotQuery(const DNSName& auth, const DNSName& server) +{ + g_dot << '"' << auth << "\" -> \"" << server << "\"" << endl; +} + +static void dotAnswer(const DNSName& dn, const DNSType& rrdt, const DNSName& server) +{ + g_dot <<"\"" << dn << "/"< \"" << dn << "/"< \"" << dn << "/CNAME\" -> \"" << target <<"\"\n"; +} + +static void dotDelegation(const DNSName& rrdn, const DNSName& server) +{ + g_dot << '"' << rrdn << "\" [shape=diamond]\n"; + g_dot << '"' << server << "\" -> \"" << rrdn << "\"\n"; +} + /** This attempts to look up the name dn with type dt. The depth parameter is for trace output. the 'auth' field describes the authority of the servers we will be talking to. Defaults to root ('believe everything') @@ -187,9 +212,10 @@ ResolveResult resolveAt(const DNSName& dn, const DNSType& dt, int depth=0, const // for tres, this is not done (since we have no memory), but we do randomize: auto servers = randomizeServers(mservers); - ResolveResult ret; for(auto& sp : servers) { + dotQuery(auth, sp.first); + ret.clear(); ComboAddress server=sp.second; server.sin4.sin_port = htons(53); // just to be sure @@ -238,13 +264,14 @@ ResolveResult resolveAt(const DNSName& dn, const DNSType& dt, int depth=0, const if(dmr.dh.aa==1) { // authoritative answer. We trust this. if(rrsection == DNSSection::Answer && dn == rrdn && dt == rrdt) { cout << prefix<<"We got an answer to our question!"<(rr.get())->d_name; ret.intermediate.push_back({dn, ttl, std::move(rr)}); // rr is DEAD now! cout << prefix<<"We got a CNAME to " << target <<", chasing"<(rr.get())->d_name; + + if(!dmr.dh.aa && (newAuth != rrdn || nsses.empty())) { + dotDelegation(rrdn, sp.first); + } nsses.insert(nsname); newAuth = rrdn; } @@ -284,8 +313,12 @@ ResolveResult resolveAt(const DNSName& dn, const DNSType& dt, int depth=0, const cout<< prefix << "Authoritative server gave us NS record to which this query does not belong" <getType()<<" "<toString()<