From 8e079f3a4a1ac8df6a89eaf8e8cca87bfed03c9f Mon Sep 17 00:00:00 2001 From: bert hubert Date: Wed, 9 Dec 2015 13:30:32 +0100 Subject: [PATCH] for recursor, if client added an EDNS record, add it to the response too --- pdns/pdns_recursor.cc | 62 ++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/pdns/pdns_recursor.cc b/pdns/pdns_recursor.cc index 3039229f2..7dab9f0a8 100644 --- a/pdns/pdns_recursor.cc +++ b/pdns/pdns_recursor.cc @@ -601,8 +601,11 @@ void startDoResolve(void *p) uint32_t maxanswersize= dc->d_tcp ? 65535 : min((uint16_t) 512, g_udpTruncationThreshold); EDNSOpts edo; - if(getEDNSOpts(dc->d_mdp, &edo) && !dc->d_tcp) { - maxanswersize = min(edo.d_packetsize, g_udpTruncationThreshold); + bool haveEDNS=false; + if(getEDNSOpts(dc->d_mdp, &edo)) { + if(!dc->d_tcp) + maxanswersize = min(edo.d_packetsize, g_udpTruncationThreshold); + haveEDNS=true; } ComboAddress local; listenSocketsAddresses_t::const_iterator lociter; @@ -806,43 +809,52 @@ void startDoResolve(void *p) else { pw.getHeader()->rcode=res; - if(edo.d_Z & EDNSOpts::DNSSECOK) { - auto state=validateRecords(ret); - if(state == Secure) { - pw.getHeader()->ad=1; - } - else if(state == Insecure) { - pw.getHeader()->ad=0; - } - else if(state == Bogus && !pw.getHeader()->cd) { - pw.getHeader()->rcode=RCode::ServFail; - goto sendit; + if(haveEDNS) { + if(edo.d_Z & EDNSOpts::DNSSECOK) { + auto state=validateRecords(ret); + if(state == Secure) { + pw.getHeader()->ad=1; + } + else if(state == Insecure) { + pw.getHeader()->ad=0; + } + else if(state == Bogus && !pw.getHeader()->cd) { + pw.getHeader()->rcode=RCode::ServFail; + goto sendit; + } } } + + if(ret.size()) { orderAndShuffle(ret); if(auto sl = luaconfsLocal->sortlist.getOrderCmp(dc->d_remote)) { sort(ret.begin(), ret.end(), *sl); variableAnswer=true; } - for(auto i=ret.cbegin(); i!=ret.cend(); ++i) { - pw.startRecord(i->d_name, i->d_type, i->d_ttl, i->d_class, i->d_place); - minTTL = min(minTTL, i->d_ttl); - i->d_content->toPacket(pw); - if(pw.size() > maxanswersize) { - pw.rollback(); - if(i->d_place==DNSResourceRecord::ANSWER) // only truncate if we actually omitted parts of the answer + } + if(haveEDNS) { + ret.push_back(makeOpt(edo.d_packetsize, 0, edo.d_Z)); + } + + for(auto i=ret.cbegin(); i!=ret.cend(); ++i) { + pw.startRecord(i->d_name, i->d_type, i->d_ttl, i->d_class, i->d_place); + if(i->d_type != QType::OPT) // their TTL ain't real + minTTL = min(minTTL, i->d_ttl); + i->d_content->toPacket(pw); + if(pw.size() > maxanswersize) { + pw.rollback(); + if(i->d_place==DNSResourceRecord::ANSWER) // only truncate if we actually omitted parts of the answer { pw.getHeader()->tc=1; pw.truncate(); } - goto sendit; // need to jump over pw.commit - } - } - - pw.commit(); + goto sendit; // need to jump over pw.commit + } } + if(ret.size()) + pw.commit(); } sendit:; -- 2.40.0