From b226e8fa33a0f11f8c3522303878ee6efecba85e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jul 2021 14:16:15 +0200 Subject: [PATCH] auth: Gracefully handle uncaught exceptions in the UDP path These exceptions should never bubble up to this point, but if it does it makes no sense to terminate the whole process because of it. This commit logs a message at error level and moves on to the next query, like we do in the TCP path. --- pdns/common_startup.cc | 138 ++++++++++++++++++++++------------------- 1 file changed, 74 insertions(+), 64 deletions(-) diff --git a/pdns/common_startup.cc b/pdns/common_startup.cc index f591db5697..c80607b541 100644 --- a/pdns/common_startup.cc +++ b/pdns/common_startup.cc @@ -414,11 +414,16 @@ static void sendout(std::unique_ptr& a) { if(!a) return; - - N->send(*a); - int diff=a->d_dt.udiff(); - avg_latency=0.999*avg_latency+0.001*diff; + try { + N->send(*a); + + int diff=a->d_dt.udiff(); + avg_latency=0.999*avg_latency+0.001*diff; + } + catch (const std::exception& e) { + g_log<receive(question, buffer)) { // receive a packet inline - continue; // packet was broken, try again - } + if(!NS->receive(question, buffer)) { // receive a packet inline + continue; // packet was broken, try again + } - numreceived++; + numreceived++; - if(question.d_remote.getSocklen()==sizeof(sockaddr_in)) - numreceived4++; - else - numreceived6++; + if(question.d_remote.getSocklen()==sizeof(sockaddr_in)) + numreceived4++; + else + numreceived6++; - if(question.d_dnssecOk) - numreceiveddo++; + if(question.d_dnssecOk) + numreceiveddo++; - if(question.hasEDNSCookie()) - numreceivedcookie++; + if(question.hasEDNSCookie()) + numreceivedcookie++; - if(question.d.qr) - continue; + if(question.d.qr) + continue; - S.ringAccount("queries", question.qdomain, question.qtype); - S.ringAccount("remotes", question.d_remote); - if(logDNSQueries) { - g_log << Logger::Notice<<"Remote "<< question.getRemoteString() <<" wants '" << question.qdomain<<"|"<send(cached); // answer it then inlined + diff=question.d_dt.udiff(); + avg_latency=0.999*avg_latency+0.001*diff; // 'EWMA' + continue; + } + } - if(PC.enabled() && (question.d.opcode != Opcode::Notify && question.d.opcode != Opcode::Update) && question.couldBeCached()) { - bool haveSomething=PC.get(question, cached); // does the PacketCache recognize this question? - if (haveSomething) { + if(distributor->isOverloaded()) { if(logDNSQueries) - g_log<<": packetcache HIT"<send(cached); // answer it then inlined - diff=question.d_dt.udiff(); - avg_latency=0.999*avg_latency+0.001*diff; // 'EWMA' + g_log<<": Dropped query, backends are overloaded"<isOverloaded()) { - if(logDNSQueries) - g_log<<": Dropped query, backends are overloaded"<question(question, &sendout); // otherwise, give to the distributor + try { + distributor->question(question, &sendout); // otherwise, give to the distributor + } + catch(DistributorFatal& df) { // when this happens, we have leaked loads of memory. Bailing out time. + _exit(1); + } } - catch(DistributorFatal& df) { // when this happens, we have leaked loads of memory. Bailing out time. - _exit(1); + catch (const std::exception& e) { + g_log<